如何将常量char*从C#传递给C函数?
我尝试从C#应用程序的外部DLL调用普通C函数。此函数定义为如何将常量char*从C#传递给C函数?,c#,.net,dll,pinvoke,marshalling,C#,.net,Dll,Pinvoke,Marshalling,我尝试从C#应用程序的外部DLL调用普通C函数。此函数定义为 void set_param(const char *data) 现在我在使用此函数时遇到一些问题: 如何在C代码中指定此“const”公共静态外部无效集参数(sbyte*数据)似乎遗漏了“const”部分 调用此函数时,如何传递一个普通的8位C字符串?调用set_param(“127.0.0.1”)会导致错误消息“无法从'string'转换为'sbyte'” 看起来您将使用ANSI字符集,因此您可以这样声明p/Invoke: [D
void set_param(const char *data)
现在我在使用此函数时遇到一些问题:
set_param(“127.0.0.1”)
会导致错误消息“无法从'string'转换为'sbyte'”看起来您将使用ANSI字符集,因此您可以这样声明p/Invoke:
[DllImport("yourdll.dll", CharSet = CharSet.Ansi)]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString);
NET封送拆收器负责复制字符串,并为您将数据转换为正确的类型
如果堆栈不平衡,则需要设置调用约定以匹配C DLL,例如:
[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
有关使用Windows API函数的许多示例,请参见
另请参见。A
const char*
在.NET中只是一个字符串
——托管方(尚未)理解只读参数的概念
如果您在p/Invoke上下文中使用它,那么应该声明marshallas
属性并将其封送为LPStr
。由此产生的签名看起来与
[DllImport("SomeModule.dll")]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString);
还有关于如何将本机字符串封送到托管环境的更多信息。我认为
公共静态外部void set_param(字符串数据)
应该可以工作。我认为您会在这里找到很多示例,这会导致一个异常:调用PInvoke函数“yourdll.dll::set_param”使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。@Elmi,因此您需要知道C DLL的调用约定,以便在P/Invoke中指定它。它使用的调用约定是什么?Matthew Watson:DLL有简单的未修饰的C函数,都是ANSI-C,uu declspec(dllexport)@Elmi,因此我认为您需要CallingConvention=CallingConvention.Cdecl
,但如果这不起作用,请尝试其他函数。字符串不是.NET Unicode中的吗?即使使用UTF-8编码,它如何可靠地适用于ASCII 128-255(特定于语言环境等)?@PeterMortensen对于ASCII 128-255,您将使用表示2字节字符字符串的LPWStr
。从.NET 4.7开始,LPUTF8Str
被添加到“本机”支持UTF8字符串,而不是返回IntPtr
并手动处理它们。另一方面,.NET中的字符串是UTF-16,这是Microsoft所称的Unicode,但它是Unicode iirc的另一种风格,但您可以正确地说,.NET中的字符串是Unicode。