Question

Je cherche la syntaxe correcte pour passer un tableau de struct à un C ++ non géré dll.

mes importations de dll sont appelés comme ceci

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

Dans mon code client je

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

Je sais que System :: Runtime :: InteropServices :: Maréchal a beaucoup de méthodes utiles pour faire des choses comme ça, mais je ne suis pas sûr que d'utiliser.

Était-ce utile?

La solution

Créer une version gérée du struct non géré à l'aide StructLayout.Sequential (assurez-vous de mettre les choses dans le même ordre). Vous devriez alors être en mesure de passer comme vous le feriez passer à une fonction gérée (par exemple, la validation (MyStruct [] pStructs).

Par exemple, supposons que notre fonction native a ce prototype:

extern "C" {

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

}

et est défini le natif MYSTRUCT comme suit:

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

Alors en C #, vous définissez une version gérée du struct comme suit:

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

Et le prototype géré comme suit:

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

Vous pouvez ensuite appeler la fonction faisant passer un tableau de struct de myStruct comme suit:

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

Autres conseils

Vous pouvez utiliser Marshall.StructureToPtr pour obtenir un IntPtr qui pourrait être passé dans un tableau natif MyStruct de *.

Cependant, je ne suis pas sûr de savoir comment le faire à partir d'une liste directement. Je crois que vous avez besoin de convertir en un tableau et d'utiliser un pin_ptr (pour empêcher le GC de se déplacer votre mémoire) avant de passer au code natif.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top