1

構造体配列をアンマネージ C++ dll に渡すための正しい構文を探しています。

私のdllインポートはこのように呼び出されます

    #define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool _Validation(/* array of struct somehow */);

私のクライアントコードでは

List<MyStruct^> list;
MyObject::_Validation(/* list*/);

System::Runtime::InteropServices::Marshal には、このようなことを行うための便利なメソッドがたくさんあることは知っていますが、どれを使用すればよいかわかりません。

4

2 に答える 2

3

StructLayout.Sequential を使用して、管理されていない構造体の管理されたバージョンを作成します (必ず同じ順序で配置してください)。その後、任意のマネージ関数 (Validation(MyStruct[] pStructs) など) に渡すのと同じように渡すことができるはずです。

たとえば、ネイティブ関数に次のプロトタイプがあるとします。

extern "C" {

STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems);

}

ネイティブ MYSTRUCT は次のように定義されます。

struct MYSTRUCT
{
    int a;
    int b;
    char c;
};

次に、C# で、構造体のマネージ バージョンを次のように定義します。

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MYSTRUCT
{
    public int a;
    public int b;
    public byte c;
}

マネージド プロトタイプは次のとおりです。

    [System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")]
    public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems);

次に、次のように MYSTRUCT 構造体の配列を渡して関数を呼び出すことができます。

    static void Main(string[] args)
    {
        MYSTRUCT[] structs = new MYSTRUCT[5];

        for (int i = 0; i < structs.Length; i++)
        {
            structs[i].a = i;
            structs[i].b = i + structs.Length;
            structs[i].c = (byte)(60 + i);
        }

        NativeMethods.fnStructInteropTest(structs, structs.Length);

        Console.ReadLine();
    }
于 2009-04-09T17:14:48.950 に答える
1

Marshall.StructureToPtrを使用して、ネイティブの MyStruct* 配列に渡すことができる IntPtr を取得できます。

ただし、リストから直接これを行う方法がわかりません。ネイティブ コードに渡す前に、これを配列に変換し、pin_ptr (GC がメモリを移動しないようにするため) を使用する必要があると思います。

于 2009-04-09T16:49:29.997 に答える