2009-08-24 6 views
0

je la fonction C suivante:Conversion cette signature C à C# P/Invoke

int w_ei_connect_init(ei_cnode* ec, const char* this_node_name, 
         const char *cookie, short creation); 

ei_cnode ressemble à ceci:

typedef struct ei_cnode_s { 
    char thishostname[EI_MAXHOSTNAMELEN+1]; 
    char thisnodename[MAXNODELEN+1]; 
    char thisalivename[EI_MAXALIVELEN+1]; 
    char ei_connect_cookie[EI_MAX_COOKIE_SIZE+1]; 
    short creation; 
    erlang_pid self; 
} ei_cnode; 

Ce que j'ai converti en C#:

[StructLayout(LayoutKind.Sequential)] 
public struct cnode { 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, 
     SizeConst = Ei.MAX_HOSTNAME_LEN + 1)] 
    public string thishostname; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, 
     SizeConst = Ei.MAX_NODE_LEN + 1)] 
    public string thisnodename; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, 
     SizeConst = Ei.MAX_ALIVE_LEN + 1)] 
    public string thisalivename; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, 
     SizeConst = Ei.MAX_COOKIE_SIZE + 1)] 
    public string ei_connect_cookie; 
    public short creation; 
    public erlang_pid self; 
} 

Je ne suis pas bon avec les pointeurs ou C en général, donc je ne suis pas sûr de savoir comment je suis censé fournir un cnode à ei_connect_init. Que signifierait la signature C# équivalente pour la fonction C ci-dessus?

Répondre

2

Chaque fois que vous voulez passer une structure C# à une valeur de paramètre contenant la structure native équivalente mais avec un pointeur, la méthode typique consiste à étiqueter le paramètre comme "ref". Cela provoque la couche PInvoke essentiellement passer l'adresse.

[DllImport("somedll")] 
public static extern w_ei_connect_init(
    ref cnode v, 
    [In] string this_node_name, 
    [In] string cookie, 
    int16 creation); 
+0

Donc je n'ai pas besoin des MarshalAsAttributes? –

+0

@David, non dans ce cas, car les valeurs par défaut sont corrects. Bien qu'il soit probablement préférable de les ajouter pour être explicite. – JaredPar

1

Quelque chose comme cela devrait fonctionner:


int w_ei_connect_init(ref cnode ec, 
     [MarshalAs(UnmanagedType.LPStr)] string this_node_name, 
     [MarshalAs(UnmanagedType.LPStr)] string cookie, short creation); 

Vous devriez également envisager de marquer votre struct avec

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

attribut, de sorte que ceux Tstr seront ansi-strings, non unicode.

+0

Parfait! Merci! –