我正在尝试为win32,mac os,linux,iOs等平台创建一个抽象层。 我希望这是动态链接。在不支持这一点的平台上,它应该不是问题,因为从我所看到的,可以编译为动态库的所有内容都可以编译为静态库,并且对代码的影响最小。
现在,为了达到这个目的:
我创建了一个名为IThread的接口和一个名为CThread的类。我使用一个名为CreateThread的函数,该函数使用extern“C”定义,以便能够将其导出并在库外调用它。这里的问题是在win32中,例如已经有一个名为CreateThread的函数,因此我得到一个链接器错误。我理解错误以及它出现的原因,但我不确定避免这种情况的好方法。我不喜欢使用奇怪的命名,因为qt使用像CreateQtThread 我的另一个想法是创建一个创建CThread实例的线程管理器/工厂,但我不确定这是个好主意。
你们对此有何看法?我问,因为我不想急于处理这样的重要组织问题。
非常感谢
答案 0 :(得分:5)
我使用一个名为CreateThread的函数,该函数使用extern“C”定义,以便能够将其导出并在库外调用它。
这很糟糕。我不能谈论其他平台,但在Windows上导出C ++函数是完美的。它们只是被破坏了,如果有人更改声明,你会得到一些完整性检查。实际上,这是导出 C ++的函数的唯一正确方法。如果您将其声明为extern“C”,则不会获得任何名称空间,也不会超载,并且如果异常从您的函数中逃脱,则编译/EHsc
的人将遇到麻烦。
首选解决方案:不要将它们声明为extern“C”,并将它们放在命名空间中。
唯一的其他解决方案:好吧,猜猜为什么所有这些C库都将其函数加上their_lib_prefix_function
...
答案 1 :(得分:5)
你决定使用extern“C”在我看来是合理的,因为它允许从其他语言,编译器等访问。但这样做意味着你不能使用命名空间,所以你只需要在你的函数前面加上一些东西来识别它们来自你的图书馆,如果你愿意的话,就是穷人的名字。
如果您想使用extern“C”,这是您必须做出的妥协。
答案 2 :(得分:5)
好吧,我不知道你是否会喜欢这个,因为我知道我合作的C开发人员发现它不美观。但是,它非常简单,可以防止这样的冲突。 (this answer中或多或少提及“his_lib_prefix_function”注释。)
因此,每当我使用C代码时,我习惯使用下划线'命名'我的函数。所以,假设您的命名空间为MegaAbstraction
,那么CreateThread
之类的内容就会变成MegaAbstraction_CreateThread
。十分简单。并且没有冲突,除非其他人拥有名为MegaAbstraction的命名空间,在这种情况下,我建议找到一个不太可能被其他人使用的命名空间。 ;)
答案 3 :(得分:1)
你的CreateThread是否使用stdcall调用约定(又名WINAPI)?如果使用cdecl调用约定,它应该将函数名称导出为_CreateThread
,并避免与Win32 CreateThread函数的链接冲突。
extern "C" _declspec(export) int _cdecl CreateThread(...
答案 4 :(得分:0)
Qt中没有“CreateQtThread”功能,甚至没有相似之处。有一个QThread类,它有构造函数。如果需要,您可以将所有内容放在命名空间中。