2009-04-08 6 views
8

J'ai la structure suivante en C#:Comment marshaller des structures en C#?

[StructLayoutAttribute(LayoutKind.Sequential)] 
public struct RECORD 
{ 
    public uint m1; 
    public uint m2; 
    public uint m3; 
} 

Je dois aussi passer un tableau (longueur fixe) de ces struct vers le code natif, qui écrit des données à ces structures. Le tableau est alloué en C# et transmis à la DLL Cll. J'ai déclaré la fonction importée comme:

[DllImport("marshall.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern void doIt(RECORD[] dataRecord); 

mais je ne reçois aucune donnée. J'ai déjà essayé l'assistant PInvoke Interop. Dois-je utiliser IntPtr ici? Des idées?

Edit:

Voici le code C# pour appeler la fonction native:

RECORD[] rec = new RECORD[256]; 
doIt(rec); 
// values of rec are all zero here 

Voici la fonction C:

int doIt(RECORD* rec) 
{ 
    // deref pointer and write some data 
} 

Répondre

13

Je suis loin d'être un P/Invoke expert, mais je me demande si en faire un paramètre in/out peut aider:

DllImport("marshall.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern void doIt([In, Out] RECORD[] dataRecord); 

Je n'aurais pas attendue cela devrait être nécessaire cependant, comme avec LayoutKind.Sequential J'espère que votre struct est déjà un type blittable, et que le tableau serait blittable aussi.

+0

Cela a fait l'affaire, merci. Y a-t-il d'autres endroits où ces mots-clés sont utilisés? Je ne les ai jamais vus auparavant – SDD

+1

De MSDN: [se référant aux tableaux de types blittable] Toutefois, ces types sont en fait marshalés en tant que paramètres In, et vous devez appliquer les attributs InAttribute et OutAttribute si vous souhaitez marshal l'argument en tant que In/Out paramètre. – SDD

+0

Merci cela a fonctionné pour moi - et mis fin à une lutte de deux heures pour y arriver. –

Questions connexes