如何在c ++中使用返回类型std :: map导出函数

时间:2018-05-03 07:37:39

标签: c++ function stdmap

我在visual c ++中有一个DLL项目和一个CLR项目。

DLL项目是导出std :: map类型函数的项目。我将从我的CLR项目中调用该函数。

来自DLL项目, staff.h

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://css-tricks.com/examples/HorzScrolling/jquery.mousewheel.js"></script>
<div class="horizontal-scroll">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>

staff.cpp

#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>;
} 

但是当我尝试编译我的DLL项目时,我遇到了一些错误:

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));
    }
}

我无法找到与此问题相关的任何解决方案。

2 个答案:

答案 0 :(得分:6)

您无法使用C链接导出非平凡的C ++类,编译器会在错误消息中告诉您。

问题是为什么你首先使用C链接?如果您不必使用C链接,请不要使用它。这将使事情变得更加复杂,因为您需要几乎所有东西的包装器。只要您使用相同的编译器就可以了。

因此,在标题源文件中,如果可以,请从签名中删除extern "C"(在任何一种情况下:从源文件中删除它,否则您在那里重新定义函数这导致后两个错误)。

如果无法删除extern "C"部分,请尝试返回空指针(void*)而不是std::map,并将其转换为CLR项目中的地图指针。但这会迫使您使用托管C ++作为CLR语言。

我不知道您的CLR项目是什么,但如果它是用托管C ++编写的,那么您可以使用所有标准C ++类型,因此C ++链接非常好。如果您的CLR项目使用不同的语言(如C#),请考虑在托管C ++中创建另一个项目,并将其用作C# dll <--> managed C++ dll <--> C++ dll之类的包装器。

答案 1 :(得分:1)

我对这类问题没有经验,但是如何创建像:

这样的函数
extern "C" STAFFS_API const char* GetStaffMapValue(int key);

extern "C" const char* GetStaffMapValue(int key) {
   auto it = staffMap.find(key);
   if (it == staffMap.end())
      return nullptr;
   else 
      return it->second.c_str();          
}

您当然可以类似地为地图修饰符创建包装器,例如,用于插入新元素。