2013-09-03 5 views
0

J'essaye d'employer pinvoke pour marshal une structure de C à C#. Alors que je suis capable de rassembler un intptr je ne peux pas trouver la syntaxe pour marshaler un double pointeur. Le pointeur int et le double pointeur sont tous deux utilisés du côté C pour allouer un tableau d'ints ou de doubles.Comment marshaler un double pointeur?

Voici le struct C:

struct xyz 
{ 
     int *np; // an int pointer works fine 
     double *foo; 
}; 

Et voici la classe C#:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public class xyz 
{ 
    Intptr np; // works fine 
      // double *foo ?? 
    } 

Je suis incapable de trouver des instructions sur la façon de marc

+0

IntPtr est juste un pointeur: jusqu'à void *; ainsi vous pouvez essayer de marshaling "double * foo" comme "IntPtr foo"; –

+0

IntPtr ne signifie pas "pointeur sur nombre entier". MSDN: le type IntPtr est conçu pour être un entier dont la taille est spécifique à la plate-forme. Il peut pointer vers n'importe quelles données. –

+0

Clarification: le code C fait tout le alloc/libre de la mémoire, donc le côté C# est béatement inconscient de tout cela. – PaeneInsula

Répondre

0

Vous semblez penser que IntPtr est un pointeur sur un int. Ce n'est pas le cas. Un IntPtr est un entier qui a la même largeur qu'un pointeur. Donc IntPtr est 32 bits de large sur x86, et 64 bits de large sur x64. Le documentation rend tout cela clair.

Le type natif équivalent le plus proche de IntPtr est void*, un pointeur non typé.

donc votre classe en C# devrait être:

[StructLayout(LayoutKind.Sequential)] 
public class xyz 
{ 
    IntPtr np; 
    IntPtr foo; 
} 

Pour lire la valeur scalaire np fait référence à appeler Marshal.ReadInt32. Et pour l'écrire appelez Marshal.WriteInt32. Mais plus probablement, puisqu'il s'agit d'un pointeur, le pointeur fait référence à un tableau. Dans ce cas, vous utilisez la surcharge Marshal.Copy appropriée pour lire et écrire.

Pour que le pointeur double, si la valeur est un scalaire, il n'y a pas de méthode dans Marshal pour lire ou écrire la valeur. Mais encore une fois, il s'agit sûrement d'un tableau dans ce cas, utilisez Marshal.Copy pour accéder au contenu.

+0

Vous confondez IntPtr avec un tableau de pointeurs. La façon de faire cela, j'ai découvert, est: [MarshalAs (UnmanagedType.ByValArray, SizeConst = 20)] public IntPtr [] np ;. Vous pouvez trouver ce lien utile: http: //stackoverflow.com/questions/18647501/marshal-array-of-doubles-from-c-to-c-sharp – PaeneInsula

+0

Je ne suis pas confus du tout. Votre ByValArray ne correspond à rien dans cette question. –

+0

Lisons à nouveau ma réponse. J'ai déclaré que "Un IntPtr est un entier qui a la même largeur qu'un pointeur." Et que "Le type natif équivalent le plus proche de IntPtr est void *, un pointeur non typé." De cela, il est clair que ma compréhension d'IntPtr est solide. –

Questions connexes