我正在开发一个允许其用户(位于同一进程中的其他库)交换数据缓冲区和流的库。该库必须可以从 MSVC 和 mingw 代码中使用(更多的兼容性不会受到伤害,但不是绝对必要的)。为了实现这一点,核心功能应该由一个小的、编译器兼容的接口提供,该接口稍后可以被使用客户端代码编译的便利层隐藏。
该库的一个具有挑战性的方面是它必须是可扩展的,以便客户端可以提供自己的缓冲区和流实现,但核心库接口在发布后必须保持稳定。如果您对进一步的背景感兴趣,您可以在论坛主题讨论中阅读它。
我试图了解编译器之间的二进制兼容性问题,但由于我是这个主题的新手,我会对我的结果的评论感兴趣。我对这里的标准定义行为不感兴趣(结构可能无法通过该测试),只对 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);
}
编辑:这个项目已经搁置了一段时间,如果它再次被搁置,可能需要重新考虑。不过我还是把这个问题留了下来,因为我仍然对答案感兴趣。