我在 Visual C++ 中有一个 DLL 项目和一个 CLR 项目。
DLL 项目是导出 std::map 类型函数的项目。我将从我的 CLR 项目中调用该函数。
从 DLL 项目, 员工.h
#ifdef STAFFS_EXPORTS
#define STAFFS_API __declspec(dllexport)
#else
#define STAFFS_API __declspec(dllimport)
#endif
#include <string>
#include <map>
namespace Staffs {
// other exported functions
....
//
extern "C" STAFFS_API auto GetStaffMap() -> std::map<int, std::string>;
}
员工.cpp
namespace Staffs {
std::map<int, std::string> staffMap;
extern "C" auto GetStaffMap() -> std::map<int, std::string> {
return staffMap;
}
void display_json(json::value const & jvalue, utility::string_t const & prefix)
{
// some code being skipped here
.......
//
staffMap.insert(std::make_pair(key, value));
}
}
但是当我尝试编译我的 DLL 项目时,出现了一些错误:
Error C2526 'GetStaffMap': C linkage function cannot return C++ class 'std::map<int,std::string,std::less<int>,std::allocator<std::pair<const _Kty,_Ty>>>' AmsCppRest c:\users\laptop-attendance\source\repos\amscpprest\amscpprest\staff.h 18
Error C2556 'std::map<int,std::string,std::less<int>,std::allocator<std::pair<const _Kty,_Ty>>> Staffs::GetStaffMap(void)': overloaded function differs only by return type from 'void Staffs::GetStaffMap(void)' AmsCppRest c:\users\laptop-attendance\source\repos\amscpprest\amscpprest\staff.cpp 38
Error C2371 'Staffs::GetStaffMap': redefinition; different basic types AmsCppRest c:\users\laptop-attendance\source\repos\amscpprest\amscpprest\staff.cpp 38
我找不到与此问题相关的任何解决方案。
最佳答案
您不能使用 C 链接导出非平凡的 C++ 类,编译器会在错误消息中告诉您。
问题是你为什么首先使用C链接?如果您不必使用 C 链接,请不要使用它。这将使事情变得更加复杂,因为几乎所有东西都需要包装器。只要您使用相同的编译器就没问题。
因此在您的 header 和 源文件中,删除extern "C"
如果可以,请从签名中删除(在任何一种情况下:将其从源文件中删除,否则您会在那里重新定义导致后两个错误的函数)。
如果您无法删除 extern "C"
部分,尝试返回一个空指针( void*
)而不是 std::map
并将其转换为 CLR 项目中的 map 指针。但这将迫使您使用托管 C++ 作为 CLR 语言。
我不知道您的 CLR 项目是什么,但如果它是用托管 C++ 编写的,您也可以在那里使用所有标准 C++ 类型,因此 C++ 链接非常好。如果您的 CLR 项目使用不同的语言(如 C#),请考虑在托管 C++ 中创建另一个项目并将其用作包装器,如 C# dll <--> managed C++ dll <--> C++ dll
.
关于c++ - 如何在 C++ 中导出具有返回类型 std::map 的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50149416/