2011-11-09 58 views
1

我宣佈原型一些C++函數如下:的mingw32 g ++以及STDCALL @suffix

extern "C" void __stdcall function(); 

我也有一些第三方與出口function() dll的 - 沒有名字的裝飾可言。 由於MinGW的stdcall @ -suffix,我無法構建我的exe或dll,原因是undefined reference to [email protected]。如何獲得沒有@ ...的對象文件...只是簡單的函數名稱?

回答

2

man ld爲您提供--enable-stdcall-fixup選項,用於鏈接非非 - 裝飾庫。我不確定主要下劃線是否會成爲問題,您必須嘗試。

如果要使用mingw生成目標文件或DLL並希望不使用「@」導出名稱,則--kill-at是您的朋友。

+0

不,這不行。另外,如果我記得對,stdcall fixups會自動適用,並且只能使用--disable。我在尋找的是刪除@ –

+0

當你想鏈接到@的時候,這就是stdcall fixups的用途。或者你想用mingw構建一個DLL,並且沒有用@輸出符號? – thiton

+0

正如我之前所說的,我有一些第三方dll與導出函數(並且此函數可能必須通過stdcall調用 - 因爲它用於一些舊的VisualBasic示例中),並且根本沒有裝飾,並且我編寫了C++ extern函數。我真正需要的是沒有@ -suffix的對象文件。通過這種方式,我可以測試兩次:1)通過C++執行,2)在VisualBasic中測試我的C++中間體,以消除一些可能的指針等相關問題。但沒有任何工作,我已經嘗試過g ++選項,objcopy,... –

6

聽起來好像您正在嘗試使用MinGW編譯使用來自第三方DLL的外部C函數的程序。有一種方法可以將這些外部函數導出到MinGW的gnu ld鏈接器可以使用的正確導入庫中,但它涉及創建一個.def定義文件。這樣做的好處是,一旦你創建了一個合適的導入庫,你就不必使用像--add-stdcall-alias--kill-at這樣的開關,因爲導入庫將包含編譯器和鏈接器所期望的符號。

這裏是這樣做的過程中一個大致的輪廓:

  1. 你需要一個工具呼叫dlltool.exe應包含在同一MinGW/bin目錄編譯器。
  2. 您需要創建一個定義文件(* .def),列出您有興趣導入的所有外部函數。
  3. 通過運行dlltool傳遞創建的.def文件作爲輸入來創建導入文件存根(* .a)。
  4. 構建項目時將新創建的導入文件* .a傳遞給鏈接器,以便可以正確解析符號。

這裏的定義文件的樣子:

;Run the dlltool like this: 
;dlltool -k -d third_party.def -l libthird_party.a 
LIBRARY third_party.dll 

EXPORTS 
    [email protected] 
    [email protected] 
    [email protected] 
; ... 
    [email protected] 

幾個重要的事情需要注意。 EXPORTS部分必須按照工具鏈的預期列出導出的符號/功能同名裝飾格式。在這種情況下,MinGW編譯器和ld鏈接程序期望__stdcall C函數附加一個'@',後面跟隨參數中的字節數。第二件重要的事情是,dlltool -k將刪除'@',這與您已經看到的--kill-at選項的作用相同。最終的結果是你有一個正確的內部名稱裝飾的導入庫,所以事情正確解決,該內部名稱將映射到您的黨的dll中找到的導出的可見名稱。

最後一件事情需要提及。在整個例子中,我們是,假設 dll中的未修飾名稱使用了__stdcall,這不一定是真的。下面的圖表(taken from here)顯示不同的編譯器是如何裝點__cdecl VS __stdcall不同:

    MSVC DLL 
Call Convention | (dllexport) | DMC DLL  | MinGW DLL | BCC DLL 
---------------------------------------------------------------------------- 
__stdcall  | [email protected] | [email protected] | [email protected] | Function 
__cdecl   | Function | Function | Function | _Function 

它是由你來確保該調用約定匹配正確或風險堆棧損壞而神祕的程序崩潰。