C连接函数不能返回C ++类 - 由我的方法的内容导致的错误

时间:2014-03-08 00:38:23

标签: c++ extern managed-c++ linkage vc90

我正在导出一个可以从非托管代码调用的方法,但该函数本身存在于托管的c ++项目中。以下代码导致编译器错误:

error C2526: 'System::Collections::Generic::IEnumerator<T>::Current::get' : C linkage function cannot return C++ class 'System::Collections::Generic::KeyValuePair<TKey,TValue>'
error C2526: 'System::Collections::Generic::Dictionary<TKey,TValue>::KeyCollection::GetEnumerator' : C linkage function cannot return C++ class 'System::Collections::Generic::Dictionary<TKey,TValue>::KeyCollection::Enumerator'

extern "C"
__declspec( dllexport )
bool MyMethod(std::string &name, std::string &path, std::map<std::string, std::string> &mymap)
{
  System::Collections::Generic::Dictionary<System::String ^, System::String^> _mgdMap = gcnew System::Collections::Generic::Dictionary<System::String ^, System::String ^>();

  // Blah blah processing
}

稍微调查一下这个错误,问题通常与标记为'extern“C”'的方法的定义有关。那么为什么它会关注方法内部的内容呢?

如果我注释掉字典初始化,或者将其切换为HashTable,一切都会很好地编译。

以下也适用 - 如果不是在本地定义字典,而是通过在方法中初始化来避免局部变量。

bool status = CallAnotherMethod(ConvertToDictionary(mymap));

其中ConvertToDictionary被声明为

System::Collections::Generic::Dictionary<System::String ^, System::String ^>^ ConvertToDictionary(std::map<std::string, std::string> &map)
{
}

这告诉我这是一个看似随意的错误。我仍然想了解为什么编译器认为这是一个问题。

2 个答案:

答案 0 :(得分:2)

如果你在C ++中编写一个要从C调用的函数,你就不能在它的接口(参数和返回类型)中使用任何而不是简单的C.这里所有你的参数是C ++对象。

答案 1 :(得分:2)

对不起尸体但是我需要与某人分享我的快乐:)

似乎你可以通过创建两个包装器来解决这个问题 - 一个用于外部呼叫标记为&#34; extern C&#34;和一个内部呼叫。在这种情况下,外面的所有东西&#34; extern C&#34;将像往常一样执行.NET代码。

主题启动者在这里回答了问题 - C++/CLI->C# error C2526: C linkage function cannot return C++ class

void DummyInternalCall(std::string &name, std::string &path, std::map<std::string, std::string> &mymap)
{
   System::Collections::Generic::Dictionary<System::String ^, System::String^> _mgdMap =  gcnew System::Collections::Generic::Dictionary<System::String ^, System::String ^>();

  // Blah blah processing
}

extern "C" __declspec( dllexport )
bool MyMethod(std::string &name, std::string &path, std::map<std::string, std::string> &mymap)
{
   DummyInternalCall(name, path, mymap);
}