从dll导出std :: vector时链接错误 [英] Linking errors while exporting std::vector from dll
问题描述
我有一个使用__ declspec(dllexport)
导出结构的dll( my_library.dll
).由于此结构包含 std :: vector< std :: wstring>成员
,我还为此导出了函数:
I have a dll (my_library.dll
) that exports a struct using __declspec(dllexport)
. Since this struct contains an std::vector<std::wstring> member
, I've also exported functions for it like so:
template class __declspec(dllexport) std::allocator<std::wstring>;
template class __declspec(dllexport) std::vector<std::wstring>;
请注意,我已经定义了宏,以便在编译时dll导出到struct和vector之上,并在其他应用程序使用dll时通过(导入 __ declspec(dllimport))
导入它们.上面的dll构建良好.
Please note that I've defined macros such that dll exports above struct and vector when compiling and they are imported (via __declspec(dllimport))
when the dll is being used by another application.
The above dll builds fine.
现在,此my_library.dll(和相应的 my_library.lib
)已链接到exe( my_exe.exe
).该exe文件具有一个.cpp文件( exe_source.cpp
),该文件定义了一个 global std :: vector< std :: wstring>
变量.此源文件可以正常编译.但是,在构建此exe时,出现以下错误:
Now this my_library.dll (and the corresponding my_library.lib
) is linked to an exe (my_exe.exe
). This exe has a .cpp file (exe_source.cpp
) that defines a global std::vector<std::wstring>
variable. This source file compiles fine.
However when building this exe, I get the following error:
my_library.lib(my_library.dll):错误LNK2005:公共:__thiscallstd :: vector,class std :: allocator
my_library.lib(my_library.dll) : error LNK2005: "public: __thiscall std::vector,class std::allocator
,std :: allocator类,std :: allocator类
,class std::allocator,class std::allocator
::〜vector,类std :: allocator,class std :: allocator,class 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
::~vector,class std::allocator ,class std::allocator,class 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) already defined in exe_source.obj
我怀疑my_library.dll是否已定义并导出了所有 std :: vector< std :: wstring>
函数,并使用了全局 std :: vector< std:
变量还会导致许多 exe_source.cpp
中的:wstring> std :: vector< std :: wstring>
函数的定义,从而导致链接程序抱怨可以找到此类功能的多个定义.
What I suspect is that the my_library.dll has all std::vector<std::wstring>
functions defined and exported, and using the global std::vector<std::wstring>
variable in the exe_source.cpp
is also resulting in definition of many std::vector<std::wstring>
functions, leading to linker complaining that multiple definitions of such functions are found.
我能正确理解错误吗?
以及如何解决此问题?
感谢您的时间.
推荐答案
首先,在DLL接口上具有STL类是高度限制的设计选择:实际上,DLL和其他模块都使用它(例如,由DLL客户端构建的EXE)必须使用相同 C ++编译器版本构建,并链接到CRT DLL的相同风格.
First, having STL classes at DLL interfaces is a highly constraining design choice: in fact, both the DLL and the other modules using it (e.g. the EXE built by your DLL clients) must be built with the same C++ compiler version and linking to the same flavor of the CRT DLL.
更好的设计选择是使用纯C接口导出DLL(实现可以使用C ++,但您应该拼凑公共API以使其成为C),或使用类似于COM的方法导出 C ++抽象接口,如
Better design choices would be exporting a DLL with a pure C interface (the implementation can use C++, but you should flatten the public API to make it C), or use a COM-like approach of exporting C++ abstract interfaces, as suggested in this CodeProject article.
假设您已意识到这一点,则应该可以删除以下行:
Assuming you are aware of that, you should be able to remove the lines:
template class __declspec(dllexport) std::allocator<std::wstring>;
template class __declspec(dllexport) std::vector<std::wstring>;
并仅导出托管您的STL数据成员的结构,例如:
and just export the structure hosting your STL data members, for example:
MyLib.h
#pragma once
#ifndef MYLIB_API
#define MYLIB_API __declspec(dllimport)
#endif
#include <string>
#include <vector>
struct MYLIB_API MyLib_Data
{
std::vector<std::wstring> Strings;
// ... other stuff ...
};
MyLib.cpp
#define MYLIB_API __declspec(dllexport)
#include "MyLib.h"
// ... Implementation code ...
请注意,您可能会收到警告C4251,例如:
Note that you may receive a warning C4251, something like:
'MyLib_Data::Strings' : class 'std::vector<std::wstring,std::allocator<_Ty>>'
needs to have dll-interface to be used by clients of struct 'MyLib_Data'
但您可以忽略它.
这篇关于从dll导出std :: vector时链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!