2010-01-30 6 views
0

Je p-invoquant dans une DLL qui renvoie une liste void ** de pointeurs de structure, tous du même type. From what I've read, afin de lancer et d'extraire ma structure de cette liste, la structure doit être considérée comme non gérée. Les principaux coupables de la struct j'essaie de rassembler plus sont les suivantes deux champs du côté C:Marshaling une structure tout en le gardant "non géré"

char name[1024]; 
int crop[4]; 

La plupart des guides suggèrent d'utiliser la chaîne ou int [] sur la struct correspondante du côté géré, mais avoir ces champs en fait une structure gérée et donc incapable d'extraire de la liste vide **.

Quelle est une autre façon de rassembler ces champs qui me donne une structure non managée?

Répondre

1

La structure mobilisera sans aide ou besoin pour le mot-clé dangereux si vous déclarez comme ceci:

using System.Runtime.InteropServices; 
... 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public struct Example { 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] 
    public string name; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 
    int[] crop; 
    } 

Convertir le vide * à la structure avec Marshal.PtrToStructure().

+0

Cela est utile pour rendre la structure un peu plus conviviale, même si j'ai toujours besoin de code non sécurisé pour accéder à toutes les structures de la liste. – RandomEngy

+0

Cela ne devrait pas être nécessaire, il devrait être couvert par Marshal.ReadIntPtr() s'il s'agit d'un vide **. Il n'y a pas assez de détails dans votre message pour dire comment la liste a été implémentée, liste liée vs tableau de pointeurs. –

+0

Ahh, c'est vrai. – RandomEngy

1

Vous pouvez utiliser le mot-clé fixed pour créer un tampon avec un tableau de taille fixe dans une structure de données:

unsafe struct Foo 
{ 
    public fixed byte name[1024]; 
    public fixed int crop[4]; 
} 

static unsafe void DumpCrops(void** ptr, int count) 
{ 
    Foo** p = (Foo**)ptr; 

    for (int i = 0; i < count; i++) 
    { 
     Foo* f = p[i]; 

     for (int j = 0; j < 4; j++) 
     { 
      Console.WriteLine(f->crop[j]); 
     } 
    } 
} 
+0

Merci, cela a fait l'affaire. – RandomEngy

0

Vous devez ajouter une ligne à ce moment-là sur la struct comme le montre ...

 

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public unsafe struct _FOOBAR { 
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 1024, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I2)] 
char name[1024]; 
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)] 
int crop[4]; 
}; 

Vous devez vérifier le dernier bit dans le bit d'attribut, UnmanagedType ...

espoir qui aide, Meilleures salutations, Tom.

Questions connexes