从dll导出std::vector时发生链接错误
Linking errors while exporting std::vector from dll
我有一个dll(my_library.dll
),它使用__declspec(dllexport)
导出结构。由于这个结构包含一个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:__thiscallstd::vector,类std::分配器
,类std::分配器,类std::分配器
::~vector,类std::分配器,类std::分配器,类std::分配器(无效)"(??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>
函数,导致链接器抱怨找到了多个此类函数的定义。
我对错误的理解正确吗?
如何解决这个问题?
谢谢你抽出时间。
首先,在DLL接口上拥有STL类是一种高度约束性的设计选择:事实上,DLL和使用它的其他模块(例如DLL客户端构建的EXE)都必须使用相同的C++编译器版本构建,并链接到风格的CRT DLL。
更好的设计选择是导出带有纯C接口的DLL(实现可以使用C++,但您应该将公共API展平以使其成为C),或者使用COM类方法导出C++抽象接口,如CodeProject文章中所建议的。
假设你知道这一点,你应该能够删除行:
template class __declspec(dllexport) std::allocator<std::wstring>; template class __declspec(dllexport) std::vector<std::wstring>;
并且只导出托管STL数据成员的结构,例如:
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,类似于:
'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'
但您可以忽略它。
- 静态数据成员的问题-修复链接错误会导致编译器错误
- Visual Studio mkl_link_tool.exe链接错误
- C++ 实现模板单例类时出现链接错误
- 使用类模板的方法链接错误
- MySQL C++连接器链接错误
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 运行 C++ 单元测试时LNK2005链接错误
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 链接错误,包括我创建的相同头文件 - C++
- 在Embarcadero C++ Builder中生成的DLL未解决的外部链接错误
- 使用标头保护的多个定义链接错误
- 链接错误:未定义对 stdscr 和 wgetch 的引用
- 使用 Vivek 的 Vcam / 捕获源过滤器构建/链接错误
- 升压program_options中的链接错误
- 使用 g++ 预处理器进行替换会导致链接错误
- 在调试配置中编译工作正常,但发布会给出链接错误
- 相邻矩阵设置链接错误
- 包含常量变量并包含在多个文件中的标头的链接错误
- C++链接错误,我理解但无法解决
- 是什么导致macOS Mojave上的GoogleTest链接错误