I'm writing a C++ library with MinGW (4.8.0, DW2, POSIX) compiler. But this library must be used by another compiler. I've read this post, so I've re-written the C++ library interface in this way:
#ifndef SERIALPORT_H
#define SERIALPORT_H
#include <cstring> // size_t
#include <memory> // unique_ptr
#if defined( _MSC_VER ) || defined( __MINGW32__ ) || defined( __MINGW64__ )
# define SERIALPORT_IMPORT __declspec( dllimport )
# define SERIALPORT_EXPORT __declspec( dllexport )
# define SERIALPORT_CALL __stdcall
#elif defined( __GNUG__ ) && !defined( WIN32 )
# define SERIALPORT_IMPORT
# define SERIALPORT_EXPORT __attribute__ ((visibility ("default")))
#else
# define SERIALPORT_IMPORT
# define SERIALPORT_EXPORT
#endif
#if defined( SERIALPORT_EXPORTS )
# define SERIALPORT_API SERIALPORT_EXPORT
#else
# define SERIALPORT_API SERIALPORT_IMPORT
#endif
namespace serialport {
/**
* @brief Milliseconds_t rappresent a duration of time expressed in milliseconds
*/
typedef unsigned long Milliseconds_t;
/**
* Possible read return value.
*/
enum ReadStatus
{
SERIAL_OK,
SERIAL_TIMEOUT,
SERIAL_ERROR
};
/**
* Interface to access to a serial port
*/
class ISerialPort {
public:
/**
* @brief operator delete overload the delete operator so we can destroy
* class inside shared library bounds.
*/
void operator delete( void* p )
{
if ( p )
{
ISerialPort* s = static_cast< ISerialPort* >( p );
s->destroy();
}
}
/**
* Get serial port path
*/
virtual const char* SERIALPORT_CALL getDeviceName() const = 0;
/**
* Get serial port baudrate
*/
virtual int SERIALPORT_CALL baudrate() const = 0;
/**
* Flush serial port rx and tx buffers.
*/
virtual void SERIALPORT_CALL flush() = 0;
/**
* @brief setTimeout set the serial port timeout
* @param timeout_ms timeout in milliseconds
*/
virtual void SERIALPORT_CALL setTimeout( Milliseconds_t timeout_ms ) = 0;
/**
* @brief getTimeoutGet serial port timeouts.
* @return serial port timeouts in milliseconds
*/
virtual Milliseconds_t SERIALPORT_CALL getTimeout() const = 0;
/**
* Read data from serial port in the specified timeout.
* @param[out] buffer pointer to the destination buffer.
* @param[in] size size in bytes of data that must be read.
* @throw SerialTimeout if a timeout occured
*/
virtual ReadStatus SERIALPORT_CALL read( void* buffer, size_t size ) const = 0;
/**
* Read data from serial port the aviable data.
* @param[out] buffer storage where to put incoming data.
* @param[in] size size in bytes of data that must be read.
* @return SerialBuffer buffer containing the data.
*/
virtual size_t SERIALPORT_CALL readSome( void* buffer, size_t size ) const = 0;
/**
* Read data from serial port in a infinite timeout.
* @param[out] buffer pointer to the destination buffer.
* @param[in] size size in bytes of data that must be read.
*/
virtual void SERIALPORT_CALL read_n( void* buffer, size_t size ) const = 0;
/**
* Send data to the serial port.
* @param[out] buffer pointer to the destination buffer.
* @param[in] size size in bytes of data that must be read.
*/
virtual void SERIALPORT_CALL send( const void* orig, size_t size ) const = 0;
protected:
/**
* @brief ~ISerialPort The destructor is protected to avoid that library is
* deleted outside dll bounds.
*/
virtual ~ISerialPort() {}
/**
* @brief destroy need to free resource: we cannot use dctor so operator delete
* will call destroy() to release the resource
*/
virtual void SERIALPORT_CALL destroy() = 0;
};
/**
* @brief The SerialDeleter class is used by SerialPtr to safely delete the class
*/
class SerialDeleter
{
public:
void operator() ( ISerialPort* s )
{
s->destroy();
}
};
} // serialport namespace
typedef std::unique_ptr < serialport::ISerialPort, serialport::SerialDeleter > SerialPtr;
/**
* Factory function for creating a serial port class
* @param path path of the serial port.
* @param baudrate baudrate of the serial port.
*/
extern "C" SERIALPORT_API serialport::ISerialPort* CreateSerialPort( const char* deviceName, int baudrate );
#endif // SERIALPORT_H
Assuming the compiler is C++11-compliant (I've tested with Visual C++ 2013), is this a good interface for cross-compiler integration?