2009-04-09 4 views
3

Je vais avoir des problèmes avec ce code:Quelqu'un peut-il expliquer la Marshal.StructureToPtr

//Creating a new ImageElement Struct 
ImageElement oElement = new UM0516.ImageElement(); 
//Create a pointer and allocate enough room for the struct type 
IntPtr pElement = Marshal.AllocHGlobal(Marshal.SizeOf(new UM0516.ImageElement())); 
//Copy the contents of the struct into the allocated memory space 
Marshal.StructureToPtr(oElement, pElement, true); 
//Function that takes a file pointed to by handle, and does some sweet sweet things 
//And returns a loaded struct pointed to by pElement 
FILES_GetImageElement(handle, el, out pElement); 

Voici où je confonds: Je vais parcourir le code, et après que j'appelle cette dernière fonction (ce qui devrait changer quelques bits dans la mémoire pointée par pElement), je vois un changement à oElement !? Je pensais que le Marshal.StructureToPtr "copie" les données d'une structure gérée en mémoire. Alors, les deux emplacements sont-ils réellement les mêmes? Struct structuré et mémoire allouée pointée par pElement?

+4

-1 pour écrire "Aides YO" et "Coo Dawg" dans le même article. –

Répondre

3

Cet article explique dans ce detail:

Formaté blittable classes ont mise en page fixe (formaté) et la représentation des données commune dans les deux gérées et de la mémoire non géré. Lorsque ces types nécessitent marshaling, un pointeur vers l'objet dans le tas est directement transmis à l' callee. L'appelé peut changer le contenu de l'emplacement mémoire référencé par le pointeur.

0

Je pense que vous n'avez probablement pas besoin d'assembler manuellement la structure à un pointeur. Tant que la version gérée de la structure correspond à la mise en page de la structure non gérée, laissez le marshaler d'interopérabilité s'occuper du marshaling.

Vous devriez être en mesure de se débarrasser de pElement entièrement et passer oElement soit comme un paramètre ref (si vous vous souciez de ce qui est en elle sur la manière) ou un paramètre out.

+0

Cela nécessite des pointeurs non sécurisés et l'instruction * fixed * en C# (comme safe int *) pour éviter que le garbage collector ne bouge la mémoire (c'est-à-dire que le memomry doit être épinglé). –

+0

Ou en utilisant System.Runtime.InteropServices.GCHandle devrait le faire (comme le dit la documentation à Marshal.StructureToPtr). –

Questions connexes