【问题标题】:Using #pragma detect_mismatch to ensure a DLL uses the correct statically linked library使用 #pragma detect_mismatch 确保 DLL 使用正确的静态链接库
【发布时间】:2011-04-15 17:54:01
【问题描述】:

我的 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 中查找该符号,并且从未找到 mismatch 指令。我想。

【问题讨论】:

  • 你在问什么?有什么问题?
  • 也许您应该在尝试使用它时添加实际的#pragma detect_mismatch 行。当然,正如 Erik 已经说过的,澄清你到底想知道什么,因为这也不完全清楚。
  • "我编译 D.dll 成功,这不应该发生。"实际的 detect_mismatch 行并不重要。
  • 这是一个有趣的链接器功能,我以前从未听说过 - MS 需要更好地记录它。

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


【解决方案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 

【讨论】:

  • @Cat:哇——你真的能这么快就验证了?
  • 在你回答之前我找到了答案。 :)
【解决方案2】:

您必须使用表示您的构建设置的预处理器构建一个字符串,并将该字符串与#pragma detect_mismatch 一起使用。

例如

#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) 链接到您的库,然后构建一个类似的字符串并将其用作库文件名的一部分:

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

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

【讨论】:

  • +1 是个好主意,我还不能这样做。我只是在为复杂的遗留代码库快速编辑一些构建设置,因为一些初级开发人员一直在混合调试和发布代码。
  • 我从现在的雇主开始就知道问题所在。我们总是因为混合调试和发布代码而出现疯狂的错误。从那时起,我们转而通过使用上述技术的“autolink.h”文件链接几乎所有内容(减去#pragma detect_mismatch,因为我们仍在使用VS 2005)。我们也在 .dll 文件的文件名中使用相同的标签。我只能推荐它,消除了很多问题。也许你可以在新项目中做类似的事情。
猜你喜欢
  • 1970-01-01
  • 2015-10-05
  • 2012-04-14
  • 2012-02-23
  • 2011-05-21
  • 2013-08-04
  • 1970-01-01
  • 2012-01-12
  • 2015-10-06
相关资源
最近更新 更多