1

出力パラメーターとして列挙型の配列へのポインターと配列の長さを受け取り、変更された値の数を返す、事前に構築された C++ API があります。この関数の目的は、後で使用するために配列に値を設定することです。独自のバージョンの列挙型を含む C# コードからこの関数を呼び出そうとしています。

C++ 関数のシグネチャは次のようになります。

static int DoAThing(SomeEnum outArray[], int length)

私のC#関数呼び出しは現在次のようになっています:

[DLLImport("API.dll", EntryPoint="DoAThing")]
public static extern int DoAThing([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4, SizeParamIndex = 1)]ref WrappedEnum[] outArray, int length);

私の呼び出しコードは次のようになります。

int length = 10;
WrappedEnum[] outArray = new WrappedEnum[length];
DoAThing(ref outArray, length);

関数を問題なく呼び出すことができますが、有用なコールスタックや情報がないマネージ コードに戻ろうとするたびに、NullReferenceException が発生し続けます。また、GCHandle.Alloc を使用して GCHandle に outArray をラップしようとしましたが、うまくいきませんでした。何か案は?

4

1 に答える 1

0

私はそれを機能させることができました。これらの手順のいくつかは不要かもしれませんが、害はないようです。

関数の先頭に SecurityPermission 属性を追加しました。

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]

呼び出しコード自体を固定ブロックでラップします。

fixed (WrapperEnum* ptr_to_enum = &outArray[0]) { DoAThing(ref outArray, length); }

また、列挙型配列を GCHandle.Alloc を使用して GCHandle にラップし、呼び出し後に解放して、適切にクリーンアップされるようにしました。

于 2013-08-12T18:06:48.820 に答える