11

C# で PInvoke を使用する方法を学習しようとして、単純な値の型を含むポインターを使用するさまざまなケースを処理する方法が少しわかりません。

アンマネージ DLL から次の 2 つの関数をインポートしています。

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

最初の関数はポインターを入力として使用し、2 番目の関数は出力として使用します。それらの使用法は、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/Invokes が発生します。

[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ますか?

4

2 に答える 2

17

ポインタが配列ではなく単一のプリミティブ型を指している場合は、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)

これらの例では、outがおそらくより適切ですが、どちらでも機能します。

于 2009-09-14T16:55:11.793 に答える
1

.NETランタイムは、その変換(「マーシャリング」と呼ばれる)の多くを実行できます。明示的な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.
于 2009-09-14T16:56:37.560 に答える