C#调用C++函数,传入string

注意:参数类型是 char*(单字节指针),还是 wchar_t*(宽字符指针)

这个要看C++那边怎么写

第一种

C++代码

extern  "C" __declspec(dllexport) void CheckString(const wchar_t* text)
{
    if (text) {
        MessageBoxW(NULL, text, L"Debug", MB_OK);
    }
}

 

C#代码

 [DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)]
 public static extern void CheckString(IntPtr text);

 private void button2_Click(object sender, EventArgs e)
 {
     string message = "hello";
     IntPtr ptr = Marshal.StringToHGlobalUni(message);//转成指针
     try
     {
         CheckString(ptr);
     }
     catch (Exception)
     {

         throw;
     }
     finally
     {
         Marshal.FreeHGlobal(ptr);//释放指针
     }

 }

 

第二种:更简单

C++代码不用改

 

C#代码

[DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern void CheckString1(string text);
private void button3_Click(object sender, EventArgs e)
{
    CheckString1("hello123");
}

如果 C++ 函数不修改字符串,C# 可以直接用 string,让 P/Invoke 自动封送,无需手动 IntPtr

  声明指定了 CharSet = CharSet.Unicode,这意味着 C# 的 string 参数会被封送为 以 null 结尾的 UTF-16 字符串,对应 C/C++ 中的 wchar_t* 类型。

 

第三种,这种是C++那边是char*

C#

 public static extern void WriteDumpLog(
            [MarshalAs(UnmanagedType.LPUTF8Str)] string moduleName,
            [MarshalAs(UnmanagedType.LPUTF8Str)] string message,
            LogLevel level);

C++

void WriteDumpLog(const char* moduleName, const char* message, LogLevel level);

 

[MarshalAs(UnmanagedType.LPUTF8Str)]作用

它强制规定:当 C# 的 string 传给 C++ 的 const char* 参数时,底层传递的字节流必须是 UTF-8 编码,而不是操作系统默认的本地编码(简体中文下是 GBK)。

总结一句话[MarshalAs(UnmanagedType.LPUTF8Str)] 就是专门为 const char* 准备的“UTF-8 编码转换器”,保证中文日志在跨语言(C# -> C++)传输后依然清晰可见。

posted @ 2026-05-29 16:35  家煜宝宝  阅读(7)  评论(0)    收藏  举报