2015-07-10 83 views
2

儘量不要對這個問題很難判斷我。不同編譯器的DLL兼容性

如果我嘗試在用MinGW工具鏈(g ++)編譯的Visual Studio項目中使用DLL(用C++編寫),會出現問題嗎?

如果答案是肯定的,有人可以解釋我爲什麼嗎?

回答

4

只要執行代碼,如果它的目標是Windows,那麼它應該運行。

對於互操作性;它取決於從dll公開的API。

  • 如果是「C」風格的API,那麼你應該沒問題。
  • 如果它是具有類和STL使用的C++ API,那麼使用不同的編譯器(甚至編譯器中的不同設置)可能會遇到麻煩。 C++沒有標準的ABI。

作爲評價和價值可能觸及這裏要注意; 「C」風格的API不僅僅是函數調用,兼容性包括(但不限於)諸如;

  • 內存分配;一般的規則是「解除分配必須由相同的代碼分配來進行」 - 即,在DLL等時所使用的匹配分配/解除分配(例如newdeletemallocfreeCustomAllocCustomDealloc
  • 數據對齊和包裝,不是所有的編譯器具有相同的默認
  • 調用約定,同樣,並非所有編譯器具有相同的默認值,如果有疑問,可以在該公約應該是什麼(如__stdcall

至於明確C++ ABI除上述所有之外,不兼容性包括Ë;

  • 名稱重整
  • STL類和容器實現的newdelete
  • 獨立和不同的實施方式中,使用自定義存儲器池等等
  • 異常的機制,例如生成和棧展開

這些都是不全面的名單,但他們在一定程度上激勵一般建議,如果可能的話,使用相同的工具鏈和相同的編譯器/連接設置

+0

例如,'的std :: string'和'性病:: Set '或'std :: cout'可能在MinGW和Visual Studio之間有不同且不兼容的實現。名稱可能會有所不同。還有異常處理。 –

+0

TBH有一個**接口**提到'std :: cout'會很奇怪。在DLL中使用'std :: cout' **完全可以。但是,不要指望MinGW端的'std :: cout << std :: hex'影響VC++端的'std :: cout'對象。 OTOH,如果你返回由'new'分配的'int *',它可能看起來是類型的C接口,但調用delete ptr的要求仍然使它成爲一個C++接口。 – MSalters

-3

不,因爲它都是一個標準。事實上,你使用gcc編譯的C++應用程序會從操作系統的dll文件中調用系統函數。所以無論你是手動還是自動調用它們,都是一樣的。

+1

錯誤。 ABI可能不同。標準C++庫內部結構(例如'std :: map'或'std :: string'的實現細節和結構佈局)是不同的。該標準定義了C++源代碼中實現的行爲。它不知道編譯器。 –

+1

對於所有downvoters和以前的評論。編譯代碼沒有區別,因爲它是機器代碼+系統調用,結構有點不同 - 這就是事實,但不是簡單的函數。但只要你用C風格編碼就沒有區別。您的程序需要Windows庫才能啓動,並會調用這些dll。所以總結起來 - 你必須做出一些thigns小心 – Chlorek

+1

但你不能切實地連接起來了'.obj'對象使用MinGW編譯成庫(包括C++標準之一)與VisualStudio中,反之亦然編譯的文件。你甚至會在基於GCC 4.9的MinGW和基於GCC 5的MinGW之間出現兼容性問題!實際上,一個C++頭文件包含很多內部'struct'-s或'class'es和'inline'-d函數(或方法),這些都是不同的......而異常處理也是不同的...... .. –

0

問題不在於DLL。這是關於如何將這種DLL描述到您的編譯器(即頭文件和導出)。

這些描述會影響您的代碼在數據佈局上的預期效果(例如,不同的編譯器可能有不同的默認對齊和填充),甚至不同的代碼路徑(例如,解析爲不同的內聯函數和宏,比如在STL情況下)。

然後每個編譯器可能有不同的名字改編方案,您可能需要一點黑客粘上代碼。

用很特殊的照顧就上述問題,你應該使用不同的編譯器一個DLL被罰款。