本文介绍了从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.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时链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 01:17