extern — функция связи 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)
{
}

Что говорит мне, что это, казалось бы, произвольная ошибка. Я все еще хотел бы понять, почему компилятор считает, что это проблема.

3

Решение

Извините за некропост, но мне нужно поделиться своим счастьем с кем-то 🙂

Кажется, что вы можете решить эту проблему, просто создав две оболочки — одну для внешнего вызова, помеченную «extern C», и одну для внутреннего вызова. В этом случае все, что находится за пределами «внешнего 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);
}
2

Другие решения

Если вы пишете функцию в C ++, которая должна вызываться из C, вы не можете использовать что-нибудь в его интерфейсе (аргументы и тип возвращаемого значения) это не просто C. Здесь все ваши аргументы являются объектами C ++.

2

По вопросам рекламы [email protected]