如何将const char*从C#传递给C函数?

Elm*_*lmi 20 .net c# dll pinvoke marshalling

我尝试从我的C#-application中调用来自外部DLL的普通C函数.此功能定义为

void set_param(const char *data)
Run Code Online (Sandbox Code Playgroud)

现在我使用这个函数有一些问题:

  1. 如何在C#代码中指定此"const"?public static extern void set_param(sbyte *data)似乎错过了"const"部分.

  2. 调用此函数时,如何移交普通的8位C字符串?调用set_param("127.0.0.1")导致错误消息"无法从'string'转换为'sbyte '"*.

Mat*_*son 30

看起来您将使用ANSI字符集,因此您可以像这样声明P/Invoke:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi)]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString);
Run Code Online (Sandbox Code Playgroud)

.NET marshaller处理字符串的复制并将数据转换为正确的类型.

如果堆栈不平衡时出错,则需要设置调用约定以匹配C DLL,例如:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
Run Code Online (Sandbox Code Playgroud)

有关使用Windows API函数的大量示例,请参见pinvoke.net.

另请参阅Microsoft关于pinvoking字符串的文档.

  • @Elmi因此我认为你想要`CallingConvention = CallingConvention.Cdecl`但是如果这不起作用的话,试试其他的. (2认同)

aev*_*tas 5

Aconst char*只是string.NET 中的 a - 托管端(尚未)理解只读参数的概念。

如果在 P/Invoke 上下文中使用它,则应声明一个MarshalAs属性并将其编组为LPStr. 生成的签名看起来像

[DllImport("SomeModule.dll")]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString);
Run Code Online (Sandbox Code Playgroud)

MSDN上还有这篇文章,其中提供了有关如何将本机字符串编组到托管环境的更多信息。