PInvoke: ошибка при возврате текста из C ++ в C # - PullRequest
4 голосов
/ 05 сентября 2011

Я использую Pinvoke для взаимодействия между собственным (C ++) кодом и управляемым (C #) кодом.Чего я хочу добиться, так это получить некоторый текст из нативного кода в мой управляемый код в качестве значения для повторного запуска, т.е. мой код C # вызывает мою функцию C ++, которая возвращает некоторый текст обратно в C #.Вот мой код для этого.

C ++ Код:

static std::wstring WSTR_TEMP;
wchar_t* cppReturnSomeText()
 {
     UnicodeString usText ("Some Text Here");
     WSTR_TEMP = ECUtilsICU::UniCodeStringToWString(usText);
     return  (wchar_t *)(WSTR_TEMP.c_str());
 }

C # Код:

[DllImport(MY_DLL_NAME]
[return: MarshalAs(UnmanagedType.LPWStr)]
private static extern string cppReturnSomeText();
public static string GetSomeText()
{
string s = cppReturnSomeText();
return s;
}

Каждыйвещь работала нормально, как и ожидалось.Теперь я просто меняю свою операционную систему с WinXP (32-битная) на Win7 (64-битная).И когда я запускаю этот код, возникает следующая ошибка:

«Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена.»

1 Ответ

2 голосов
/ 05 сентября 2011

Полагаю, проблема в том, что вы выделяете память с помощью распределителя среды выполнения C ++, но маршаллер C # пытается освободить ее. Это не может работать. Вам нужно выделить и освободить с тем же распределителем.

Лучший способ, который я знаю, чтобы решить вашу проблему - это набрать BSTR. При этом используется COM-распределитель, который рад разделиться между собственным и управляемым модулями.

#include <comutil.h>
BSTR cppReturnSomeText()
{
    UnicodeString usText("Some Text Here");
    std::wstring result = ECUtilsICU::UniCodeStringToWString(usText);
    return ::SysAllocString(result.c_str());
}

На стороне C # вы делаете это:

[DllImport(MY_DLL_NAME, CallingConvention=CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string cppReturnSomeText();

Еще одним преимуществом этого является то, что ваш код теперь потокобезопасен, потому что вам больше не нужна глобальная переменная.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...