2011-04-15 37 views
3

我有一個靜態S.lib,由我的D.dll使用。使用#pragma detect_mismatch確保DLL使用正確的靜態鏈接庫

我正在嘗試使用#pragma detect_mismatch來確保兩者都是在相同的發行版或調試設置下編譯的。

我跟着霍爾格薩斯格倫德說明這裏 http://boost.2283326.n4.nabble.com/Boost-and-Microsoft-s-SECURE-SCL-td3025203.html

DUMPBIN上S.lib顯示:

Linker Directives 
----------------- 
/FAILIFMISMATCH:"COMPILED_DEBUG=1" 
/INCLUDE:_dll_impl_interface_mismatch_check 
/DEFAULTLIB:"MSVCRTD" 
/DEFAULTLIB:"OLDNAMES" 

我編譯D.dll成功,這是不應該的。在D.dll的D.lib

DUMPBIN顯示:

Linker Directives 
----------------- 
/FAILIFMISMATCH:"COMPILED_DEBUG=2" 
/INCLUDE:_dll_impl_interface_mismatch_check 
/DEFAULTLIB:"uuid.lib" 
/DEFAULTLIB:"uuid.lib" 
/FAILIFMISMATCH:"_MSC_VER=1600" 
/FAILIFMISMATCH:"_ITERATOR_DEBUG_LEVEL=2" 
/DEFAULTLIB:"msvcprtd" 
/DEFAULTLIB:"MSVCRTD" 
/DEFAULTLIB:"OLDNAMES" 

任何幫助將不勝感激。

編輯:

我意外地定義了。在我的靜態庫的符號「dll_impl_interface_mismatch_check」和我的消費DLL。這意味着符號在靜態庫S.lib中沒有找到,並且從來沒有找到不匹配指令。我認爲。

+0

什麼你問?問題是什麼? – Erik 2011-04-15 17:59:37

+0

也許你應該添加實際的'#pragma detect_mismatch'行來嘗試使用它。當然,正如Erik已經說過的那樣,澄清你到底想知道什麼,因爲這也不完全清楚。 – 2011-04-15 18:39:54

+0

「我成功編譯D.dll,這不應該發生。」實際的detect_mismatch行並不重要。 – 2011-04-15 18:43:29

回答

1

我只是猜測在這裏 - 我必須在今晚試驗一下。

Holger Grund的說明針對依賴於DLL的對象而設計。在你的情況下,DLL依賴於靜態庫。

所以,我猜你希望_dll_impl_interface_mismatch_check對象被添加到靜態庫而不是DLL。因此,而不是:

extern "C" const char dll_impl_interface_mismatch_check=0; 

cl /c /Zl foo.cpp 
lib D.lib foo.obj 

嘗試:

extern "C" const char dll_impl_interface_mismatch_check=0; 

cl /c /Zl foo.cpp 
lib S.lib foo.obj 
+0

@Cat:哇 - 你真的能夠很快驗證這一點嗎? – 2011-04-15 18:41:26

+0

我在回答之前找到了答案。 :) – 2011-04-15 18:55:51

1

您必須使用表示您的構建設置的預處理器構建一個字符串,並使用該字符串與#pragma detect_mismatch

E.g.

#if defined(_DEBUG) 
    #define FOO_DEBUG_PART "_debug" 
#else 
    #define FOO_DEBUG_PART "_release" 
#endif 

#if defined(_MT) 
    #define FOO_CRT_PART1 "_MT" 
#else 
    #define FOO_CRT_PART1 "_st" 
#endif 

#if defined(_DLL) 
    #define FOO_CRT_PART2 "_DLL" 
#else 
    #define FOO_CRT_PART2 "_LIB" 
#endif 

// ... 

#define FOO_BUILD_SETTINGS FOO_DEBUG_PART FOO_CRT_PART1 FOO_CRT_PART2 /* ... */ 

#pragma detect_mismatch("foo_build_settings", FOO_BUILD_SETTINGS) 

海事組織更好的解決方案,雖然是用#pragma comment(lib)鏈接到您的圖書館,然後建立一個類似的字符串,並把它作爲LIB文件名的一部分:

// build FOO_BUILD_SETTINGS like above 
#pragma comment(lib, "mylib" FOO_BUILD_SETTINGS) 

這樣你不能使用錯誤的庫(除非你改變代碼或者lib是用錯誤的文件名創建的......或者之後重命名)。當然,如果你像我一樣偏執,你總是可以同時做這兩件事:)

+0

+1是一個好主意,我還不能做到這一點。我只是快速編輯一些令人費解的遺留代碼庫的一些構建設置,因爲一些初級開發人員不斷混合調試和發佈代碼。 – 2011-04-15 18:41:32

+0

我從當初的僱主開始就知道這個問題。我們有瘋狂的錯誤源於混合調試和發佈代碼。從那以後,我們通過使用上述技術(「#pragma detect_mismatch」,因爲我們仍在使用VS 2005)的「autolink.h」文件切換到幾乎所有的鏈接。我們也在.dll文件的文件名中使用了相同的標籤。我只能推薦它,消除了很多問題。也許你可以在新項目中做類似的事情。 – 2011-04-15 18:55:57