2009-08-24 9 views
0

我有下面的C函數:轉換該C簽名C#中的P/Invoke

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

ei_cnode看起來是這樣的:

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; 

我已經轉換爲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; 
} 

我不擅長與一般的指針或C,所以我不知道我怎樣,我應該提供一個cnodeei_connect_init

對於上面的C函數,等效的C#簽名是什麼?

回答

2

無論何時您想要將C#結構傳遞給包含等效本機結構但帶有指針的參數值,典型方法都是將該參數標記爲「ref」。這導致PInvoke層基本上通過地址。

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

所以我不需要MarshalAsAttributes? – 2009-08-24 17:41:59

+0

@David,沒有在這種情況下,因爲默認值是正確的。儘管將它們添加爲明確可能會更好。 – JaredPar 2009-08-24 17:44:01

1

像這樣的東西應該工作:


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

你也應該考慮與

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

屬性標記你的結構,所以那些TSTR將是ANSI-字符串,不是Unicode。

+0

完美!謝謝! – 2009-08-24 17:40:35