我正在研究一個庫,允許其用戶(駐留在同一進程中的其他庫)交換數據緩衝區和流。該庫必須可以從MSVC和mingw代碼中使用(更多兼容性不會受到傷害,但並非絕對必要)。爲了實現這一點,核心功能應該由一個小的,兼容編譯器的接口提供,稍後可以通過用客戶端代碼編譯的便利層隱藏。MSVC和mingw之間的界面二進制兼容嗎?
圖書館所面對的挑戰是,它必須是可擴展的,這樣客戶可以提供自己的緩衝區和流實現,但是一旦它被釋放的核心庫的接口必須保持穩定。如果您對進一步的背景感興趣,可以在forum thread discussion中閱讀。
我試圖瞭解編譯器之間的二進制兼容性的問題,但由於我是新來這個話題我有興趣在我的結果的意見。我對這裏的標準定義行爲不感興趣(結構可能無法通過該測試),只有在兼容mingw和MSVC的情況下,如果方便的話可以使用或其他編譯器。
特別是,將結構兼容?它們一律由函數指針組成,所以我不認爲填充會成爲問題。另外,這裏是必需的stdcall約定,還是cdecl也能工作?我可以不指定它,因爲這兩個編譯器將默認爲cdecl?我是不是該?以下是我現在所擁有的:
#include <stdint.h>
typedef struct {
uint32_t (__stdcall *read)(void*, uint8_t*, uint32_t);
void (__stdcall *write)(void*, const uint8_t*, uint32_t);
uint32_t (__stdcall *getBytesLeft)(void*);
uint8_t (__stdcall *destroy)(void*);
} SharedStreamInterface;
typedef struct {
uint32_t (__stdcall *read)(void*, uint8_t*, uint32_t);
void (__stdcall *write)(void*, const uint8_t*, uint32_t);
uint32_t (__stdcall *getBytesLeft)(void*);
uint8_t (__stdcall *destroy)(void*);
uint32_t (__stdcall *getreadpos)(void*);
uint32_t (__stdcall *getwritepos)(void*);
uint32_t (__stdcall *getlength)(void*);
void (__stdcall *setreadpos)(void*, uint32_t);
void (__stdcall *setwritepos)(void*, uint32_t);
void (__stdcall *setlength)(void*, uint32_t);
} SharedBufferInterface;
extern "C" {
// Functions applicable for both buffers and streams
__stdcall uint32_t readData(uint32_t id, uint8_t* data, uint32_t size);
__stdcall void writeData(uint32_t id, const uint8_t* data, uint32_t size);
__stdcall uint32_t getBytesLeft(uint32_t id);
__stdcall void destroyStreamOrBuffer(uint32_t id);
__stdcall uint8_t streamOrBufferExists(uint32_t id);
// Functions only applicable for buffers
__stdcall uint32_t getReadPos(uint32_t id);
__stdcall uint32_t getWritePos(uint32_t id);
__stdcall uint32_t getLength(uint32_t id);
__stdcall void setReadPos(uint32_t id, uint32_t pos);
__stdcall void setWritePos(uint32_t id, uint32_t pos);
__stdcall void setLength(uint32_t id, uint32_t length);
__stdcall uint8_t bufferExists(uint32_t id);
// Adding new buffers/Streams
__stdcall uint32_t addStream(SharedStreamInterface *interface, void *stream);
__stdcall uint32_t addBuffer(SharedBufferInterface *interface, void *buffer);
}
編輯:這是爲那些已經擱置了一段時間了,可能該項目需要大量的重新思考,如果這是有史以來unshelved再次的。儘管如此,我仍然留下了這個問題,因爲我仍然對答案感興趣。
我會使用條件規定了那些呼籲convs,MSVC下造成的,它不是安全的假設,它會默認爲'__cdecl',因爲這可以很容易地與項目設置進行覆蓋。 – Necrolis 2011-05-22 11:21:38