Pregunta

Tengo una estructura no administrado Me gustaría reunir a do sostenido que se ve básicamente como esto:

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

Creo que tengo que escribir un contador de referencias de encargo, pero no estoy seguro de cómo proceder.

¿Fue útil?

Solución

Me gusta usar una configuración de este tipo cuando no es necesario que los niños índice directamente:

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

Si hace necesitan directamente del índice de los niños, lo más fácil es crear un método GetChild (mostrada a continuación). La forma más difícil es la creación de una clase de ayuda / envoltura que implementa IList<MyStruct>. Un ejemplo sería devuelto de la propiedad Children, y su interior funcionaría mediante una llamada al método GetChild. Esto se deja como ejercicio para el lector en caso de que lo necesite.

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

Otros consejos

Si desea sólo para pasarlo a alguna función no administrado, es posible que utilices código inseguro y stackalloc / fijar una matriz para obtener un puntero a la matriz de objetos.

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


        }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top