Pregunta

Estoy buscando la sintaxis correcta para pasar una matriz a una estructura C ++ no administrado DLL.

mis importaciones dll se denominan como esto

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

En mi código de cliente tengo

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

Yo sé sistema de tiempo de ejecución :: :: :: InteropServices Mariscal tiene una gran cantidad de métodos útiles para hacer cosas como esta, pero no estoy seguro acerca de cuál utilizar.

¿Fue útil?

Solución

Crea una versión administrada de la estructura no administrado utilizando StructLayout.Sequential (asegúrese de poner las cosas en el mismo orden). A continuación, debería ser capaz de pasarlo parecido a lo que pasa a cualquier función administrada (por ejemplo, Validación (MyStruct [] pStructs).

Por ejemplo, digamos que nuestra función nativa tiene este prototipo:

extern "C" {

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

}

y el MYSTRUCT nativa se define de la siguiente manera:

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

A continuación, en C #, se define una versión administrada de la estructura de la siguiente manera:

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

Y el prototipo conseguido de la siguiente manera:

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

A continuación, puede llamar a la función pasándole una serie de estructuras myStruct de la siguiente manera:

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

Otros consejos

Puede utilizar Marshall.StructureToPtr para obtener una IntPtr que podría pasar a un nativo MyStruct * matriz.

Sin embargo, no estoy seguro de cómo hacer esto de una lista directamente. Creo que necesita para convertir esto en una matriz y utilizar un pin_ptr (para evitar que el GC se mueva de su memoria) antes de pasarlo al código nativo.

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