Frage

Ich habe eine nicht verwaltete Struktur I c scharf Marschall möchte, dass im Grunde wie folgt aussieht:

struct MyStruct{  
    /* ... some stuff ... */
    int numChilds;  
    MyStruct *childs;
}

Ich glaube, dass ich habe eine benutzerdefinierte Einweiser zu schreiben, aber ich bin nicht sicher, wie es weitergehen.

War es hilfreich?

Lösung

Ich mag eine Einrichtung wie diese zu benutzen, wenn ich Index Kinder brauchen nicht direkt:

struct MyStruct
{
    /* ... some stuff ... */
    int numChilds;
    IntPtr childData;

    public IEnumerable<MyStruct> Children
    {
        get
        {
            int elementSize = Marshal.SizeOf(typeof(MyStruct));
            for (int i = 0; i < this.numChilds; i++)
            {
                IntPtr data = new IntPtr(this.childData.ToInt64() + elementSize * i);
                MyStruct child = (MyStruct)Marshal.PtrToStructure(data, typeof(MyStruct));
                yield return child;
            }
        }
    }
}

Wenn Sie tun müssen direkt Index Kinder, die einfachste Sache ein Verfahren GetChild schafft (siehe unten). Je härter Weg ist die Schaffung einer Helfer / Wrapper-Klasse, die IList<MyStruct> implementiert. Ein Beispiel wäre der Children Eigenschaft zurückgegeben werden, und seine interne funktionieren würde, durch die GetChild Methode aufrufen. Dies bleibt als Übung für den Leser sollte er es braucht.

public MyStruct GetChild(int index)
{
    if (index < 0)
        throw new ArgumentOutOfRangeException("index", "The index must be >= 0.");
    if (index >= this.numChilds)
        throw new ArgumentException("The index must be less than the number of children", "index");

    int elementSize = Marshal.SizeOf(typeof(MyStruct));
    IntPtr data = new IntPtr(childData.ToInt64() + elementSize * index);
    MyStruct child = (MyStruct)Marshal.PtrToStructure(data, typeof(MyStruct));
    return child;
}

Andere Tipps

Wenn Sie nur wollen, dass es bis zu einem gewissen nicht verwalteten Funktion zu übergeben, können Sie nur unsicheren Code verwenden und stackalloc / ein Array fixieren einen Zeiger auf das Array von Objekten zu erhalten.

        unsafe struct Foo
        {
            public int value;
            public int fooCount;
            public Foo* foos;
        }

        [DllImport("dll_natv.dll")]
        static extern void PrintFoos(Foo f);

        public unsafe static void Main()
        {
            Foo* foos = stackalloc Foo[10];

            for (int i = 0; i < 10; ++i)
                foos[i].value = i;

            Foo mainFoo = new Foo();
            mainFoo.fooCount = 10;
            mainFoo.value = 100;
            mainFoo.foos = foos;

            PrintFoos(mainFoo);


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