Платформа Invoke, bool и string - PullRequest
5 голосов
/ 11 октября 2010

предположим, что dll содержит следующие функции

extern "C" __declspec(dllexport) void f(bool x)
{
   //do something
}
extern "C" __declspec(dllexport) const char* g()
{
   //do something else
}

Мой первый наивный подход к использованию этих функций из C # был следующим:

[DllImport("MyDll.dll")]
internal static extern void f(bool x);
[DllImport("MyDll.dll")]
internal static extern string g();

Первое удивление состояло в том, что C ++ bool нене конвертировать в C # bool (странное поведение во время выполнения, но без сбоев, хотя).Поэтому мне пришлось изменить bool на байт и вручную конвертировать из одного в другой.Итак, первый вопрос заключается в том, есть ли лучший способ маршалирования bool (обратите внимание, что это bool, а не BOOL)

Вторым сюрпризом было то, что необработанная строка, возвращаемая функцией dll, была OWNED строкой C #,не копируется, как я и ожидал, и в конечном итоге код C # освобождает память, возвращаемую DLL.Я узнал об этом, потому что программа потерпела крах, но затем я изменил тип возвращаемого значения на sbyte * и вручную инициализировал строку с указателем, который уже выполняет копирование.Итак, второй вопрос: 2.1: Есть ли лучший способ предотвратить владение указателем для маршаллированной строки.2.2: WTF ?!Почему C # делает это?Я имею в виду, очевидный случай, когда функция dll возвращает литерал, а C # пытается удалить его ...

Заранее спасибо, и, надеюсь, мои вопросы не являются расплывчатыми или непонятными.

Ответы [ 2 ]

5 голосов
/ 11 октября 2010
[DllImport("MyDll.dll")]
internal static extern void f( [MarshalAs(UnmanagedType.I1)] bool x );
[DllImport("MyDll.dll")]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string g();
5 голосов
/ 11 октября 2010

. По умолчанию .NET маршалы между C ++ BOOL (4 байта) и .NET bool автоматически. Для типа C ++ bool (однобайтового) необходимо указать способ маршалинга:

[DllImport("MyDll.dll")]
internal static extern void f([MarshalAs(UnmanagedType.I1)] bool x);
...