Возврат std :: string из C ++ DLL в программу на c # -> неверный адрес, указанный для RtlFreeHeap - PullRequest
9 голосов
/ 28 апреля 2009

В функции в моей C ++ DLL я возвращаю std :: string в мое приложение c #. Это выглядит примерно так:

std::string g_DllName = "MyDLL";

extern "C" THUNDER_API const char* __stdcall GetDLLName()
{
    return g_DllName.c_str();
}

Но когда мой код C # вызывает эту функцию, я получаю это сообщение в моем окне вывода:

Invalid Address specified to RtlFreeHeap( 00150000, 0012D8D8 )

Объявление функции в c # выглядит так:

[DllImport("MyDll", EntryPoint = "GetDLLName")]
    [return: MarshalAs(UnmanagedType.LPStr)]
    public static extern string GetDLLName();

Из того, что я смог найти в Интернете, иногда это сообщение появляется, когда есть несоответствие между тем, какая версия new (отладка или выпуск и т. Д.) Используется с delete. Но я не уверен, что это происходит в моем случае. Так что я не уверен, что именно это вызывает. Может быть, MashallAs может иметь к этому какое-то отношение?

Есть идеи?

Спасибо!

1 Ответ

12 голосов
/ 28 апреля 2009

Мне удалось найти проблему. Это был способ определения C #. Из того, что я могу понять, использование MarshallAs (UnmanagedType.LPStr) в сочетании с возвращаемым типом строки делает его так, что оно попытается освободить строку, когда это будет сделано. Но поскольку строка происходит из C ++ DLL и, скорее всего, совершенно другого менеджера памяти, она завершается неудачно. И даже если это не сработало, я все равно не хочу, чтобы оно было освобождено.

Решение, которое я нашел, состояло в том, чтобы изменить объявление C # на это (код C ++ не изменился):

[DllImport("MyDll", EntryPoint = "GetDLLName")]
public static extern IntPtr GetDLLName();

Так что это делает так, что он просто возвращает указатель на строковые данные. А затем, чтобы изменить его на строку, передать его Marshal.PtrToStringAnsi ()

return Marshal.PtrToStringAnsi(GetDLLName());

И это включается в другую функцию для чистоты.

Я нашел решение на этой странице: http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&ixPost=1108

...