Получение строк из unmanaged code
Но когда кода у меня в С++ описана функция как
а в С# ее ищет функция
[CODE=C#][DllImport("MyLyb.dll")]
private static extern string GetString(IntPtr objectHandle)[/CODE]
то в дебаге я получаю исключение
Пробовал добавить атрибут
Пробовал строку запихать в параметры и пометить как выходной параметр:
[DllImport("MyLyb.dll")]
private static extern voud GetString(IntPtr objectHandle, out string resultString);
Получаю пустую строку, на этот раз без исключения.
Так как правильно получить строку из unmanaged code?
[DllImport("MyLyb.dll")]
private static extern voud GetString(IntPtr objectHandle,[Out,MarshalAs(UnmanagedType.LPWStr)] StringBuilder resultString);
Вместо out попрробуй использовать ref.
Также CharSet попробуй указать для DLL, а то мб за пределы строки вылазит.
Пробовал все CharSet'ы.
А как StringBuilder правильно инициализировать?
UPD: С ref возвращается пустая строка.
О! уже лучше :) Посмотри на wiki какие именно :D
Также попробуй другой UnmanagedType
Забавная таблица :)
Своих крякозябр я не нашел. У меня похоже на японский.
Другие типы сейчас поперебираю.
Попробовал LPWStr, LPTStr, LPStr. На последнем варианте крякозябры поменялись, и все равно ни на что не похожи. На других типах UnmanagedType прога ругается, что можно указывать только вышеуказанные типы.
Значит, вот что есть на данный момент после всех изменений:
DLL:
{
//resultString = (wchar_t*)((AlgorithmDinamicProg*)pAlgorithm)->GetTextResult();
resultString = L"abcЭЮЯ";
}
Объявление:
private static extern void GetTextResult(IntPtr algorithmHandle, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder stringBuilder);
Использование:
GetTextResult(_algorithmHandler, stringBuilder);
ResultString = stringBuilder.ToString();
Результат:
И вот пример с мсдн.
Стоп. Разве по умолчанию типа char в .NET не двубайтовый? (пруф раз и пруф два)
К слову, я только из-за этого в С++ сделал wchar_t.
И вот пример с мсдн.
Никак :(
Получает пустую строку.
А может быть проблема в С++'коде? У меня есть возможность его менять. Может стоит воспользоваться виндовыми дейфайнами, и проводить мой результат к LPTSTR?
И еще момент. У меня в С++ коде можно видеть, что идет приведения результата моих внутренних процедур к wchar_t*. Идет это от const wchar_t*. В этом может быть проблема?
SUCCESS!!!
На втором методе, через указатель на участок памяти и IntPtr получилось!
Остается только гадать, почему не получилось сделать это напрямую.
Пока буду делать так, но если придумаете, как строку в явном виде получить, с интересом почитаю :)
В результате код:
[CODE=C#][DllImport("MyLib.dll")]
private static extern int GetResult(IntPtr algorithmHandle, [Out] out IntPtr resultPointer);[/CODE]
на выходе дает нулевой указатель. В плюсах, как и раньше, на месте второго параметра стоит (void*). Пробовал еще делать так: [In, Out] ref IntPtr resultPointer, но исход тот же.
Что неправильно?
Остается только гадать, почему не получилось сделать это напрямую.
Потому что он пытается потом освободить память по указателю, чего ему не дают сделать :) Так что таким методом тебе нужно будет самому следить за освобождением памяти.
А первый метод не работает?
Да я бы не против самому следить за памятью, но он все равно мне либо ничего не возвращает, либо возвращает фигню. Хрен с не с памятью, хоть бы что-нибудь вернул =)
Не работает. В StringBuilder оказывается пустая строка.
Если в плюсах использовать в параметре не wchar_t*, а wchar_t**, то в StringBuilder оказываются знакомые нам крякозябры. Лучше, чем пустая строка, но в целом не то =)
[QUOTE=Cybernetic]Не успел нарадоваться. Хотел вернуть указатель строку через выходной параметр, а не return-выражение.
В результате код:
[CODE=C#]
[DllImport("MyLib.dll")]
private static extern int GetResult(IntPtr algorithmHandle, [Out] out IntPtr resultPointer); [/CODE]
на выходе дает нулевой указатель. В плюсах, как и раньше, на месте второго параметра стоит (void*). Пробовал еще делать так: [In, Out] ref IntPtr resultPointer, но исход тот же.
Что неправильно?[/QUOTE]
Проблема решилась, когда вместо void* стал указывать void**.
Sorry, был не прав. Это запись в текстовый файл у соответствующих классов .NET по умолчанию в UTF-8 кодировке производится.