从dll导出std :: vector时链接错误 [英] Linking errors while exporting std::vector from dll

查看:153
本文介绍了从dll导出std :: vector时链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用__ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆