问题描述
我有一个使用__ 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.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 ++抽象接口,如此CodeProject文章.
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时链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!