Как передать const char * функции C из С#?

Я пытаюсь вызвать обычную C-функцию из внешней DLL из моего С# -приложения. Эти функции определяются как

void set_param(const char *data)

Теперь у меня есть некоторые проблемы с использованием этой функции:

  • Как указать эту константу в С# -коде? public static extern void set_param(sbyte *data), похоже, пропустит часть "const".

  • Как передать стандартную 8-битную C-строку при вызове этой функции? Вызов set_param("127.0.0.1") приводит к сообщению об ошибке: "невозможно преобразовать из" string "в" sbyte "*.

Ответы

Ответ 1

Похоже, вы будете использовать набор ANSI char, чтобы вы могли объявить P/Invoke следующим образом:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi)]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString);

Маршаллер .NET обрабатывает копии строк и преобразовывает данные в нужный тип.

Если у вас есть ошибка с неуравновешенным стеком, вам нужно будет установить соглашение о вызове в соответствии с вашей DLL, например:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

См. pinvoke.net для большого количества примеров с использованием функций Windows API.

Также см. Документация Microsoft на выводные строки.

Ответ 2

A const char* является просто a string в .NET - управляемая сторона еще не понимает понятие параметров только для чтения.

Если вы используете это в контексте P/Invoke, вы должны объявить атрибут MarshalAs и маршалить его как LPStr. Результирующая подпись будет выглядеть примерно так:

[DllImport("SomeModule.dll")]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString);

В этой статье на MSDN содержится дополнительная информация о том, как упорядочить собственные строки в управляемой среде.