Problème:Impossible struct unmarshal du code non managé dans Mono
Je peux rassembler avec succès un struct avec des éléments de racines ainsi que les éléments du tableau dans le code non managé, mais ne peut pas obtenir les données de l'élément racine arrière (les éléments du tableau venir retour correct). J'ai essayé un certain nombre d'approches, mais aucune n'a fonctionné jusqu'à présent. Voici le plus simple ci-dessous.
J'ai lu à http://www.mono-project.com/Interop_with_Native_Libraries et penser que je fais tout correctement (mais évidemment pas ;-)
Mise en œuvre:
C#: déclarations
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct Vector3
{
public float x;
public float y;
public float z;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MeshData
{
[MarshalAs(UnmanagedType.LPArray)]
public Vector3[] vertices;
public int verticeCount;
}
[DllImport("MeshPlugin")]
private static extern bool ImportMesh([In, Out, MarshalAs(UnmanagedType.LPStruct)] MeshData meshData);
déclarations autochtones C:
#pragma pack(1)
typedef struct VECTOR3
{
float x;
float y;
float z;
} VECTOR3;
#pragma pack(1)
typedef struct MESHDATA
{
VECTOR3 *vertices;
int verticeCount;
} MESHDATA;
appelé de C# comme ceci:
<defined vertices and length...>
MeshData meshData = new MeshData();
meshData.vertices = mesh.vertices; // note that vertices[0].x = 111
meshData.verticeCount = 1;
ImportMesh(meshData); // calls native function
Debug.Log(meshData.vertices[0].x); // prints 222 which is correct, so array got marshaled back okay
Debug.Log(meshData.verticeCount); // **prints 1 which is incorrect** so the int element did not come back okay
Implémentation native:
bool ImportMesh(MESHDATA *meshData)
{
printf("%f", meshData->vertices[0].x); // prints 111 which is correct
meshData->vertices[0].x = 222; // change to see if it gets back okay
printf("%d", meshData->verticeCount); // prints 1 which is correct
meshData->verticeCount = 2; // change to see if it gets back okay
return true;
}
Le problème est que les valeurs sous-tableau de struct sont correctement retournés, mais que les principaux éléments struct ne sont pas.
J'ai aussi essayé cela en C#:
[DllImport("MeshPlugin")]
private static extern bool ImportMesh(IntPtr meshData);
int size = Marshal.SizeOf(typeof(MeshData));
IntPtr pMeshData = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(meshData, pMeshData, false);
ImportMesh(pMeshData);
meshData = (MeshData)(Marshal.PtrToStructure(pMeshData, typeof(MeshData)));
Marshal.FreeHGlobal(pMeshData);
Et celui-ci se bloque mal sur le retour (mais le journal indique que le code natif exécuté et imprimé les valeurs correctes du côté natif).
J'ai essayé d'autres permutations avec des décorateurs d'attributs, etc., mais le compilateur mono a suggéré de supprimer certains des attributs car ils n'étaient pas nécessaires, ce que j'ai fait.
J'ai été googler et craquer ma tête sur ceci pendant 2 jours maintenant, et n'importe quelle aide est très appréciée!
Merci Rolf. La chose amusante est que le tableau des sommets fonctionne déjà, ce sont les ints dans la structure qui ne le sont pas. Dans votre changement suggéré, je ne vois aucun changement dans la façon dont le verticeCount est marshalé? À votre santé! –
Un paramètre ref n'est pas nécessairement appelé de la même manière qu'un paramètre [In, Out, MarshalAs (UnmanagedType.LPStruct)] :) –
Mais dites-vous que je dois faire le Marshal.AllocHGlobal sur tout? Par exemple. le MeshData obtient un Marshal.AllocHGlobal et aussi le tableau vertices obtient un distinct? –