Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将常量char*从C#传递给C函数?_C#_.net_Dll_Pinvoke_Marshalling - Fatal编程技术网

如何将常量char*从C#传递给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

我尝试从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:

    [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。