簡體   English   中英

C ++ Builder導出cdecl以供跨平台使用

[英]C++ Builder exporting cdecl for cross platform use

我有一個最初用MSVS編寫的庫(dll),我需要使它跨平台(Mac / Win)。 我開始使用XCode,但是使用新的Embarcadero C ++構建器XE3,我認為一個開發環境將是更好的選擇。 主機應用程序是用Delphi編寫的,因此有更多理由將其移至一組工具。

對於我現有的代碼,一切都是cdecl,但是我無法在C ++ Builder上使用它。 如果我將其轉換為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庫中的示例,例如來自序列化或來自Tcl的更簡單描述

假設在Windows庫的構建中定義了WINDOWS

#ifdef WINDOWS
  #define DLLEXPORT  __declspec( dllexport )
#else
  #define DLLEXPORT
#endif

您也可以使此定義在構建DLL或在需要__declspec( dllimport )時調用DLL時行為正確

我處理此類差異的方式始終是相同的基本思想:查看每個編譯器的工作方式,並提出一個宏或一組宏,這些宏或一組宏可以生成所有必需的形式而又不會太麻煩使用。

對於您的_cdecl,一個簡單的宏,例如“ EXPORT_CDECL”就足夠了; 然后可以根據編譯器的要求將其設置為不擴展為“ _cdecl”或“ stdcall”。

您還可以使用類似這樣的方式為名稱添加內容,例如#define EXPORT_NAME(Name) _##Name

當然,您還可以創建一個“大”宏,該宏使用各個組件(返回類型,函數名稱,函數參數)並吐出整個結果行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM