Маршал "char *" в C # - PullRequest
       35

Маршал "char *" в C #

20 голосов
/ 02 октября 2008

Учитывая следующую функцию C в DLL:

char * GetDir(char* path );

Как бы вы P / Invoke эту функцию в C # и правильно маршалировать char *. Похоже, что .NET знает, как сделать LPCTSTR, но когда я не могу понять, какой маршалинг не вызывает исключение NotSupportedException при вызове этой функции.

Ответы [ 2 ]

22 голосов
/ 02 октября 2008

Ответ OregonGhost верен только в том случае, если символ *, возвращаемый из GetDir, расположен в HGlobal или LocalAlloc. Я не могу вспомнить, какой из них, но CLR будет предполагать, что любой тип возвращаемого значения из функции PInvoke был присвоен одному или другому.

Более надежный способ - ввести возвращаемое значение GetDir как IntPtr. Затем вы можете использовать любую из функций Marshal.PtrToStringAnsi, чтобы получить строковый тип. Это также дает вам гибкость освобождения строки в соответствии с вашим выбором.


[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);

Можете ли вы дать нам какие-либо другие советы относительно поведения GetDir? Изменяет ли это входную строку? Как распределяется возвращаемое значение? Если вы можете предоставить это, я могу дать гораздо лучший ответ.

12 голосов
/ 02 октября 2008

Попробуйте

[DllImport("your.dll", CharSet = CharSet.Ansi)]
string GetDir(StringBuilder path);

строка автоматически маршалируется в строку с нулевым символом в конце, и со свойством CharSet вы указываете Marshaller, что он должен использовать ANSI, а не Unicode. Примечание: используйте строку (или System.String) для const char *, но StringBuilder для char *.

Вы также можете попробовать MarshalAs, как в этом примере .

...