使用#pragma detect_mismatch确保DLL使用正确的静态链接库

时间:2011-04-15 17:54:01

标签: c++ c visual-studio-2010 linker

我有一个由我的D.dll使用的静态S.lib。

我正在尝试使用#pragma detect_mismatch来确保两者都是在相同的发布或调试设置下编译的。

我在这里遵循了Holger Grund的指示 http://boost.2283326.n4.nabble.com/Boost-and-Microsoft-s-SECURE-SCL-td3025203.html

S.lib上的

dumpbin显示:

 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中定义了符号'dll_impl_interface_mismatch_check'。这意味着在静态库S.lib中没有查找符号,并且从未找到错配指令。我想。

2 个答案:

答案 0 :(得分: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)

IMO更好的解决方案是使用#pragma comment(lib)链接到您的库,然后构建一个类似的字符串并将其用作lib文件名的一部分:

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

这样你就不能使用错误的库(除非您更改代码或使用错误的文件名创建lib ...或者之后重命名)。当然,如果你和我一样偏执,你可以随时做到这两点:)

答案 1 :(得分: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