【发布时间】:2015-11-19 10:06:38
【问题描述】:
我有一个使用 __declspec(dllexport) 导出结构的 dll (my_library.dll)。由于该结构包含std::vector<std::wstring> member,因此我还为它导出了函数,如下所示:
template class __declspec(dllexport) std::allocator<std::wstring>;
template class __declspec(dllexport) std::vector<std::wstring>;
请注意,我已经定义了宏,这样 dll 在编译时会在结构和向量之上导出并被导入(当 dll 被另一个应用程序使用时,通过 __declspec(dllimport))。
上面的 dll 构建良好。
现在这个 my_library.dll(和相应的my_library.lib)链接到一个exe(my_exe.exe)。这个 exe 有一个 .cpp 文件 (exe_source.cpp),它定义了一个 global std::vector<std::wstring> 变量。这个源文件编译得很好。
但是,在构建这个 exe 时,我收到以下错误:
my_library.lib(my_library.dll) : 错误 LNK2005: "public: __thiscall std::vector,class std::allocator
,类std::allocator,类std::allocator
::~vector,类 std::allocator ,类std::allocator,类std::allocator (void)" (??1?$vector@V?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@V?$allocator@V?$basic_string@ GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@2@@std@@QAE@XZ) 已经在 exe_source.obj 中定义
我怀疑 my_library.dll 定义和导出了所有std::vector<std::wstring> 函数,并且在exe_source.cpp 中使用全局std::vector<std::wstring> 变量也会导致定义许多std::vector<std::wstring> 函数,从而导致链接器抱怨发现此类函数的多个定义。
我是否正确理解了错误?
以及如何解决这个问题?
感谢您的宝贵时间。
【问题讨论】:
-
即使你得到这个链接,导出你真的无法控制其内部实现的 C++ 类也不是一个好主意。如果您的应用使用不同的编译器选项、不同的编译器版本等进行编译,那么
vector与 DLL 使用的vector将不同。 -
@PaulMcKenzie,感谢您的建议。但是,我认为可以正确导入向量,正如微软文章support.microsoft.com/en-us/kb/168958所建议的那样。
-
无论它是否正确,这都不是一个好主意或习惯。正如@MrC64 的回答所说,这是一个非常脆弱的设计选择。
-
你为未来积攒了大量的麻烦。忽略您所获得的建议,后果自负。
-
我想澄清一下,我鼓励 OP 遵循更好的设计选择(正如我的回答中已经写的那样),例如让 DLL 导出 纯 C 接口(C++ 是内部 DLL的实现)。
标签: c++ stl linker dllimport dllexport