从dll导出std :: vector时链接错误

时间:2015-11-19 10:06:38

标签: c++ stl linker dllimport dllexport

我有一个使用__ my_library.dll导出结构的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在编译时导出struct和vector之上,并且当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:__ thishisall   std :: vector,class std :: allocator

     
    

,类std :: allocator,类std :: allocator

         
      
        

::〜vector,class 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>个函数,并且使用std::vector<std::wstring>中的全局exe_source.cpp变量也导致了许多{{}的定义1}}函数,导致链接器抱怨找到了这些函数的多个定义。

我是否正确理解错误?

如何解决这个问题?

感谢您的时间。

1 个答案:

答案 0 :(得分:2)

首先,在DLL接口上使用STL类是高度约束设计选择:事实上,DLL和使用它的其他模块(例如,由DLL客户端构建的EXE)都必须构建使用相同的 C ++编译器版本并链接到CRT DLL的相同风格。

更好的设计选择是导出带有纯C接口的DLL(实现可以使用C ++,但是你应该将公共API扁平化为C),或使用类似于的方法导出 C ++抽象接口,如this CodeProject article中所述。

假设您知道这一点,您应该能够删除这些行:

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'

但你可以忽略它。