【发布时间】:2011-11-01 08:08:49
【问题描述】:
我想创建一个 SDK,它包含一个带有公共 API 的头文件 sdk.h 和一个带有实现的已编译 DLL。
If the code looks like:
//////////
// sdk.h
//////////
enum eAction
{
Action1,
Action2,
Action3
};
class Item
{
protected:
virtual ~Item(){}
public:
virtual void Do(eAction action) = 0;
virtual void Release() = 0;
};
extern "C"
{
Item * CreateItem();
}
//////////
// sdk.cpp
//////////
class ItemImpl: public Item
{
public:
virtual void Do(eAction action)
{
printf("%d", (int)action);
// do something
}
virtual void Release()
{
delete this;
}
};
Item * CreateItem()
{
return new ItemImpl;
}
//////////
// main.cpp client side
//////////
int main(int argc, char* argv[])
{
Item *pItem = CreateItem();
pItem->Do(Action1);
pItem->Release();
return 0;
}
// The file sdk.h is the public API.
// The file sdk.cpp is the implementation and it is compiled to sdk.dll.
// The file main.cpp is the client code that uses the SDK.
我的问题是:
如果 SDK 和客户端代码是使用不同的编译器编译的,那么在公共 API(方法 Do(action))中使用枚举参数和返回值是否安全?例如 SDK 是用 VC 编译的,客户端代码是用 gcc 编译的。不同的编译器是否可以使用不同的大小(2,4 或 8 字节)来表示枚举?
【问题讨论】:
-
标准允许不同的大小,重要的问题(我不知道答案,因此这是一个评论)是平台上的 C++ ABI(s)是否你关心的,指定如何决定枚举的底层类型。如果您不知道您关心什么平台,那么您必须将其视为不属于 ABI 的一部分,因此您不能将
enum传递到可执行边界,就像传递std::string一样。 -
我认为这是现实冲突的一个例子:osdir.com/ml/android-ndk/2010-10/msg00559.html。假设帖子属实,Android 的工具链默认配置为在可能的情况下使用
short枚举,但一些libstdc++dll 至少使用int。因此,适合short的枚举在两者之间是不兼容的,除非您使用-fno-short-enums进行编译。因此,如果您的“两个编译器”都是 GCC,但一个有一个没有-fshort-enums,那么您的建议可能是不安全的。如果小于int的参数作为int传递,你可能会侥幸成功。
标签: c++ api visual-c++ gcc sdk