неразрешенный внешний символ, но дампбин говорит, что все в порядке

Я скачал Crypto++ 5.62 и собрал его с настройками проекта по умолчанию. В моем проекте я указал путь к cryptopp.lib и определил его имя в «Дополнительных зависимостях». И Crypto++, и мой проект — VS 2008.

При создании моего проекта я получаю:

main.obj : error LNK2001: unresolved external symbol 
  "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const CryptoPP::DEFAULT_CHANNEL" (?DEFAULT_CHANNEL@CryptoPP@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@B)

main.obj : error LNK2001: unresolved external symbol 
  "bool (__cdecl* CryptoPP::g_pAssignIntToInteger)(class type_info const &,void *,void const *)" (?g_pAssignIntToInteger@CryptoPP@@3P6A_NABVtype_info@@PAXPBX@ZA)

dumpbin /all cryptopp.lib показывает меня в разделе общедоступных символов

19471C _imp_?DEFAULT_CHANNEL@CryptoPP@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@B

1D6F30 __imp_?g_pAssignIntToInteger@CryptoPP@@3P6A_NABVtype_info@@PAXPBX@ZA

Что случилось тогда? Почему компоновщик не может найти символы?

обновление:

командная строка компоновщика из настроек моего проекта

/OUT:"C:\Projects\crypto_hash\Debug\crypto_hash.exe" /NOLOGO /LIBPATH:"e:\libs\cryptopp\cryptopp562\cryptopp\Win32\DLL_Output\Debug" /MANIFEST /MANIFESTFILE:"Debug\crypto_hash.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Projects\crypto_hash\Debug\crypto_hash.pdb" /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT cryptopp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib


person fogbit    schedule 27.03.2014    source источник
comment
отсутствует зависимость? перепутал включать?   -  person Engineer2021    schedule 27.03.2014
comment
@staticx: я не уверен, что понимаю тебя. Не могли бы вы объяснить более подробно?   -  person fogbit    schedule 27.03.2014
comment
Вы можете посмотреть в окно вывода и посмотреть, какая команда link.exe используется?   -  person evpo    schedule 27.03.2014
comment
@evpo: я обновил свой пост   -  person fogbit    schedule 27.03.2014
comment
у вас есть два проекта в вашем решении? где ваш файл main.cpp? Это проект, который зависит от cryptopp.lib?   -  person evpo    schedule 27.03.2014
comment
@evpo: проекты разделены, каждый находится в своем собственном решении. В моем проекте используется cryptopp.lib   -  person fogbit    schedule 27.03.2014
comment
Опубликованная вами команда компоновщика исходит из cryptopp.dll, но ошибки исходят от вызывающего проекта, верно? Могу ли я увидеть команду link.exe из проекта, где находится ваш main.cpp?   -  person evpo    schedule 27.03.2014
comment
@evpo: эта командная строка компоновщика, которую я опубликовал, взята из моего собственного проекта, который использует cryptopp.dll (main.cpp находится в этом проекте), а не из проекта, который создает cryptopp.dll.   -  person fogbit    schedule 27.03.2014
comment
Тогда как вы объясните, что вывод этого проекта — OUT:Win32\DLL_Output\Debug\cryptopp.dll?   -  person evpo    schedule 27.03.2014
comment
@evpo: извините, это моя ошибка. Я обновил правильную командную строку.   -  person fogbit    schedule 27.03.2014
comment
Все в порядке. Команда компоновщика выглядит нормально для меня. Постарайтесь убедиться, что ваши переключатели компиляции совпадают между cryptopp.dll и crypto_hash.exe. Такие вещи, как /MTd и так далее.   -  person evpo    schedule 27.03.2014
comment
@evpo: если я создам cryptopp как lib, а не dll с /MDd (как в моем собственном проекте), это сработает. Но это не в случае dll. В любом случае, спасибо за помощь.   -  person fogbit    schedule 27.03.2014


Ответы (1)


Попробуйте добавить CRYPTOPP_IMPORTS в определения вашего проекта.

От config.h:

#ifdef CRYPTOPP_EXPORTS
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllexport)
#elif defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllimport)
#else
# define CRYPTOPP_DLL
#endif

Или включите Crypto++ dll.h. Он устанавливает CRYPTOPP_IMPORTS:

#if !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_DEFAULT_NO_DLL)
# ifdef CRYPTOPP_CONFIG_H
#  error To use the DLL version of Crypto++, this file must be included before any other Crypto++ header files.
# endif
# define CRYPTOPP_IMPORTS
#endif

Если это не сработает...

g_pAssignIntToInteger от algparams.cpp:

$ grep -R g_pAssignIntToInteger *
algparam.cpp:PAssignIntToInteger g_pAssignIntToInteger = NULL;
algparam.h:CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger;
algparam.h:     if (!(g_pAssignIntToInteger != NULL && typeid(T) == typeid(int) && g_pAssignIntToInteger(valueType, pValue, &m_value)))
integer.cpp:    if (!g_pAssignIntToInteger)
integer.cpp:        g_pAssignIntToInteger = AssignIntToInteger;

Глядя на объявление в algparam.h:

// to allow the linker to discard Integer code if not needed.
typedef bool (CRYPTOPP_API * PAssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt);
CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger;

И реализация в algparam.cpp:

#ifndef CRYPTOPP_IMPORTS
...

NAMESPACE_BEGIN(CryptoPP)    
PAssignIntToInteger g_pAssignIntToInteger = NULL;
...

Поэтому вам может потребоваться изменить реализацию, чтобы убедиться, что код использует g_pAssignIntToInteger (чтобы предотвратить его отбрасывание). К сожалению, сейчас ничего не приходит в голову.


DEFAULT_CHANNEL объявлен в cryptlib.h и имеет память, выделенную в cryptolib.cpp:

$ grep -R DEFAULT_CHANNEL *
...
cryptlib.cpp:const std::string DEFAULT_CHANNEL;
...
cryptlib.h:extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
...

Это может быть другая проблема, так как я не привык видеть проблемы с DEFAULT_CHANNEL. Посмотрите, как CRYPTOPP_IMPORTS работает для вас, а затем задайте другой вопрос, так как это может быть другая проблема.

person jww    schedule 02.04.2014
comment
#include ‹dll.h› до того, как все остальные крипто-включения решили проблему и для меня. - person BeschBesch; 30.01.2016