我有一个最初用 MSVS 编写的库 (dll),我需要跨平台 (Mac/Win)。我开始使用 XCode,但有了新的 Embarcadero C++ 构建器 XE3,我认为一个开发环境会是更好的方法。 主机应用程序是用 Delphi 编写的,因此更有理由将其转移到一组工具中。
对于我现有的代码,一切都是 cdecl,但我无法让它在 C++ 构建器上运行。如果我将它转换为 stdcall 那么它工作正常但据我了解我需要在 OSX 下使用库时使用 cdecl。
在 MSVC 中,我像这样导出我的函数:
extern "C" __declspec(dllexport) int Init(char * init_dir, DebugCallbackFunc f, DeviceCallbackFunc f1)
在 C++ Builder 中,我是这样导出的:
extern "C" __declspec( dllexport ) int _cdecl Init(char * init_dir, DebugCallbackFunc f, DeviceCallbackFunc f1)
问题是,当我使用 cdecl 时,Delphi 主机应用程序总是使用 GetProcAddress 返回 NULL,但如果我将其更改为 stdcall,则工作正常。
TUDMXInit = function(p: PAnsiChar; f: TDebugCallbackFunc; f1: TDeviceCallbackFunc): integer; cdecl;
我还想举个例子来说明处理“_”的最佳方法,该“_”假设在 OSX 下作为导出函数的前缀。我应该只使用条件将其添加到所有函数的前面吗?
提前致谢。 马丁
最佳答案
通常的做法是使用宏。 declspec 和 cdecl/stdcall 是特定于 Windows 的。 你想要的 OSX(和其他 Unix)中的调用是
extern "C" int Init(char * init_dir, DebugCallbackFunc f, DeviceCallbackFunc f1)
所以通常的方法是定义一个宏,例如DLL_EXPORT 有关示例,请参阅 Boost 库 例如来自 Serialisation或来自 Tcl 的更简单描述
假设 WINDOWS 已在您的 Windows 库构建中定义
#ifdef WINDOWS
#define DLLEXPORT __declspec( dllexport )
#else
#define DLLEXPORT
#endif
您还可以使此定义在构建 DLL 时正确运行,或者在需要时调用 DLL __declspec( dllimport )
关于C++ Builder 导出 cdecl 以供跨平台使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12797639/