Учитывая следующую функцию C в DLL:
char * GetDir(char* path );
Как бы вы P / Invoke эту функцию в C# и правильно маршалировали char *. .NET, похоже, знает, как выполнять LPCTSTR, но когда я не могу понять какой-либо маршалинг, который не вызывает срабатывание NotSupportedException при вызове этой функции.





Пытаться
[DllImport("your.dll", CharSet = CharSet.Ansi)]
string GetDir(StringBuilder path);
строка автоматически упорядочивается до строки с нулевым символом в конце, и с помощью свойства CharSet вы сообщаете маршаллеру, что он должен использовать ANSI, а не Unicode. Примечание: используйте строку (или System.String) для const char *, но StringBuilder для char *.
Вы также можете попробовать MarshalAs, как в этот пример.
Ответ OregonGhost верен только в том случае, если char *, возвращаемый из GetDir, выделен в HGlobal или LocalAlloc. Я не могу вспомнить, какой именно, но CLR будет предполагать, что любой строковый тип, возвращаемый функцией PInvoke, был выделен тем или другим.
Более надежный способ - ввести возвращаемый GetDir значение IntPtr. Затем вы можете использовать любую из функций Marshal.PtrToStringAnsi, чтобы получить строковый тип. Это также дает вам гибкость при освобождении струны по вашему выбору.
[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);
Можете ли вы дать нам какие-либо другие подсказки относительно поведения GetDir? Изменяет ли он входную строку? Как распределяется возвращаемое значение? Если вы можете это представить, я могу дать гораздо лучший ответ.
Аааа .... PtrToStringAnsi - это то, что я искал, тем временем я решил использовать IntPtr, но теперь столкнулся с одной загвоздкой ... Я использую .NETCF, а PtrToStringAnsi находится только в полной структуре: (
Оказывается, OpenNetCF имеет PtrToStringAnsi .... похоже, проблема решена. Помечу это как принятое, как только я смогу протестировать код.
Знает ли .NET автоматически, что нужно преобразовать StringBuilder в char * для входных параметров, или для этого требовалась какая-то сторонняя библиотека? Спасибо.
Вы знаете какие-либо причины, по которым
string ansi = Marshal.PtrToStringAnsi(ptr);будет успешным, но вернутьstringсCharSet = CharSet.Ansiне удастся?