Использование #pragma detect_mismatch, чтобы гарантировать, что DLL использует правильную статически связанную библиотеку - PullRequest
3 голосов
/ 15 апреля 2011

У меня есть статический S.lib, который используется моим D.dll.

Я пытаюсь использовать #pragma detect_mismatch, чтобы убедиться, что оба были скомпилированы с одинаковыми настройками выпуска или отладки.

Я следовал инструкциям Хольгера Грунда здесь http://boost.2283326.n4.nabble.com/Boost-and-Microsoft-s-SECURE-SCL-td3025203.html

свалка на S.lib показывает:

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

Я успешно компилирую D.dll, чего не должно быть.

dumpbin на Dlib D.lib показывает:

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"

Любая помощь будет принята с благодарностью.

EDIT:

Я случайно определил символ 'dll_impl_interface_mismatch_check' в ОБА моей статической библиотеке и моей потребляющей DLL. Это означало, что символ не был найден в статической библиотеке S.lib, а директива о несоответствии не была найдена. Я думаю.

Ответы [ 2 ]

1 голос
/ 15 апреля 2011

Я просто догадываюсь здесь - сегодня вечером мне придется поэкспериментировать с этим.

Инструкции Хольгера Грунда предназначены для объектов, которые зависят от 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 
1 голос
/ 15 апреля 2011

Вы должны построить строку с препроцессором, которая представляет ваши настройки сборки, и использовать эту строку с #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)

Таким образом, вы не сможете использоватьнеправильная библиотека (если вы не изменили код или библиотека не создана с неправильным именем файла ... или впоследствии переименована).И конечно, если вы такой же параноик, как и я, вы всегда можете сделать и то, и другое:)

...