Frage

Ich bin für die korrekte Syntax der Suche eine Struktur Array an eine nicht verwaltete C passieren ++ dll.

meine dll Einfuhren werden wie folgt genannt

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

In meinem Client-Code Ich habe

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

Ich weiß, System :: Runtime :: InteropServices :: Marshal viele nützliche Methoden hat für Sachen wie diese zu tun, aber ich bin mir nicht sicher, über die verwenden.

War es hilfreich?

Lösung

Erstellen Sie eine verwaltete Version der nicht verwalteten Struktur mit StructLayout.Sequential (stellen Sie sicher, die Dinge in der gleichen Reihenfolge setzen). Sie sollten dann in der Lage sein, es zu passieren, wie Sie es zu jeder verwalteten Funktion übergeben würden (zum Beispiel Validation (MyStruct [] pStructs).

Zum Beispiel, sagen wir mal unsere native Funktion diesen Prototyp hat:

extern "C" {

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

}

und die native MYSTRUCT ist wie folgt definiert:

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

Dann in C # definieren Sie eine verwaltete Version der Struktur wie folgt:

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

Und der verwaltete Prototyp wie folgt:

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

Sie können dann die Funktion aufrufen es eine Reihe von MYSTRUCT structs vorbei wie folgt:

    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();
    }

Andere Tipps

Sie können mit Marshall.StructureToPtr ein IntPtr zu erhalten, die in ein native MyStruct * Array übergeben werden kann.

Allerdings bin ich mir nicht sicher, wie diese direkt aus einer Liste zu tun. Ich glaube, Sie müssen diese in ein Array konvertieren und eine pin_ptr verwenden (um die GC zu verhindern, dass Ihr Gedächtnis zu bewegen), bevor es zu dem nativen Code zu übergeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top