У меня есть неуправляемая C ++ DLL, которую я обернул простым интерфейсом C, чтобы я мог вызывать PInvoke из C #.Вот пример метода в оболочке C:
const wchar_t* getMyString()
{
// Assume that someWideString is a std::wstring that will remain
// in memory for the life of the incoming calls.
return someWideString.c_str();
}
Вот моя настройка C # DLLImport.
[DllImport( "my.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl )]
private static extern string GetMyString();
Однако строка неправильно распределяется, часто портя первый символ илииногда вместо этого показывается куча китайских иероглифов.Я зарегистрировал вывод от реализации на стороне C, чтобы подтвердить, что std :: wstring сформирован правильно.
Я также попытался изменить DLLImport, чтобы он возвращал IntPtr и конвертировал с помощью упакованного метода, используя Marshal.PtrToStringUniи он имеет тот же результат.
[DllImport( "my.dll", CallingConvention = CallingConvention.Cdecl )]
private static extern IntPtr GetMyString();
public string GetMyStringMarshal()
{
return Marshal.PtrToStringUni( GetMyString() );
}
Любые идеи?
Обновить с ответом
Так что, как уже упоминалось ниже, это на самом деле не проблема с моими привязками, новремя жизни моего wchar_t *.Мое письменное предположение было неверным, someWideString фактически копировалось во время моих звонков в остальную часть приложения.Поэтому он существовал только в стеке и был освобожден до того, как мой код C # смог завершить его маршалинг.
Правильное решение - либо передать указатель на мой метод, как описано в shf301, либо убедиться, что мой wchar_t* ссылка не перемещается / не перераспределяется / не уничтожается, пока мой интерфейс C # не успел ее скопировать.
Возвращение std :: wstring вниз на мой уровень C в виде "const & std :: wstring" означает мой вызовc_str () вернет ссылку, которая не будет немедленно удалена из области действия моего метода C.
Затем вызывающему коду C # необходимо использовать Marshal.PtrToStringUni () для копирования данных из ссылки вуправляемая строка.