C linkage function cannot return C++ class - error resulting from the contents of my method

≡放荡痞女 提交于 2021-02-19 02:23:21

问题


I am exporting a method that can be called from unmanaged code, but the function itself lives in a managed c++ project. The following code results in a compiler error:

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
}

Looking into this error a little bit, the issue normally has to do with the definition of the method that is marked as 'extern "C"'. So why would it be at all concerned with what goes on inside the method?

If I comment out the Dictionary initialization, or switch it to a HashTable everything compiles beautifully.

The following works as well - if instead of defining a dictionary locally, I avoid the local variable by initializing it in a method.

bool status = CallAnotherMethod(ConvertToDictionary(mymap));

where ConvertToDictionary is declared as

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

Which tells me that this is a seemingly arbitrary error. I would still like to understand why the compiler thinks this is a problem.


回答1:


Sorry for necroposting but i need to share my happiness with somebody :)

Seems that you are able to solve this just by creating two wrappers - one for external call marked with "extern C" and one for internal call. In this case everything outside "extern C" will be executed as usual .NET code.

That was answered by the topicstarter here - 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);
}



回答2:


If you write a function in C++ that is to be called from C, you can't use anything in it's interface (arguments and return type) that isn't plain C. Here all your arguments are C++ objects.



来源:https://stackoverflow.com/questions/22263380/c-linkage-function-cannot-return-c-class-error-resulting-from-the-contents-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!