Как P / Invoke, когда задействованы указатели - PullRequest
7 голосов
/ 14 сентября 2009

Пытаясь научиться использовать PInvoke в C #, я немного не уверен, как обрабатывать различные случаи с помощью указателей, использующих простые типы значений.

Я импортирую следующие две функции из неуправляемой DLL:

public int USB4_Initialize(short* device);
public int USB4_GetCount(short device, short encoder, unsigned long* value);

Первая функция использует указатель в качестве входа, вторая - в качестве выхода. Их использование довольно просто в C ++:

// Pointer as an input
short device = 0; // Always using device 0.
USB4_Initialize(&device);

// Pointer as an output
unsigned long count;
USB4_GetCount(0,0,&count); // count is output

Моя первая попытка в C # приводит к следующему P / вызывает:

[DllImport("USB4.dll")]
public static extern int USB4_Initialize(IntPtr deviceCount); //short*

[DllImport("USB4.dll")]
public static extern int USB4_GetCount(short deviceNumber, short encoder, IntPtr value); //ulong*

Как использовать эти функции в C # таким же образом, как и код C ++, приведенный выше? Есть ли лучший способ объявить эти типы, возможно, используя MarshalAs?

Ответы [ 2 ]

12 голосов
/ 14 сентября 2009

Если указатель относится к одному типу примитива, а не к массиву, используйте ref / out для описания параметра

[DllImport("USB4.dll")]
public static extern int USB4_Initialize(ref short deviceCount);

[DllImport("USB4.dll")]
public static extern int USB4_GetCount(short deviceNumber, short encoder, ref uint32 value)

В этих примерах, вероятно, более уместно, но любой из них будет работать.

0 голосов
/ 14 сентября 2009

.NET Runtime может многое сделать для вас (называется «маршалинг») для вас. Хотя явный IntPtr всегда будет делать ТОЧНО то, о чем вы ему говорите, вы, вероятно, можете заменить ключевое слово ref указателем такого типа.

[DllImport("USB4.dll")]
public static extern int USB4_Initialize(ref short deviceCount); //short*

[DllImport("USB4.dll")]
public static extern int USB4_GetCount(short deviceNumber, short encoder, ref short value); //ulong*

Затем вы можете назвать их так:

short count = 0;

USB4_Initialize(ref count);

// use the count variable now.
...