Comment rassembler tableau C ++ / CLI de struct à C ++ non géré
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.
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.