Функция связывания C не может вернуть класс C++ - ошибка, возникающая из-за содержимого моего метода
Я экспортирую метод, который можно вызвать из неуправляемого кода, но сама функция живет в управляемом проекте 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 ответа
Извините за некропост, но мне нужно поделиться своим счастьем с кем-то:)
Кажется, что вы можете решить эту проблему, просто создав две оболочки - одну для внешнего вызова, помеченную "extern C", и одну для внутреннего вызова. В этом случае все, что находится за пределами "extern C", будет выполняться как обычный код.NET.
На это ответил автор темы - ошибка C++/CLI->C# C2526: функция связи C не может вернуть класс C++
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);
}
Если вы пишете в C++ функцию, которая должна вызываться из C, вы не можете использовать в ее интерфейсе что-либо (аргументы и тип возвращаемого значения), что не является простым C. Здесь все ваши аргументы являются объектами C++.