将此 C 签名转换为 C# 以进行 P/Invoke

发布于 2024-08-02 23:04:26 字数 1276 浏览 5 评论 0原文

我有以下 C 函数:

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,所以我不确定我应该如何向 ei_connect_init 提供一个 cnode

上面的 C 函数的等效 C# 签名是什么?

I have the following C function:

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

ei_cnode looks like this:

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;

Which I have converted to 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;
}

I'm not good with pointers or C in general, so I'm not sure how I'm supposed to supply a cnode to ei_connect_init.

What would the equivalent C# signature be for the C function above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦忆晨望 2024-08-09 23:04:26

每当您想要将 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);

Whenever you want to pass a C# struct to a parameter value containing the equivalent native struct but with a pointer, the typical method is to label the parameter as "ref". This causes the PInvoke layer to essentially pass the address in.

[DllImport("somedll")]
public static extern w_ei_connect_init(
  ref cnode v,
  [In] string this_node_name,
  [In] string cookie,
  int16 creation);
冷血 2024-08-09 23:04:26

像这样的东西应该可以工作:


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。

Something like this should work:


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

You should also consider marking your struct with

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

attribute, so those TStr will be ansi-strings, not unicode.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文