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++)传输后依然清晰可见。

浙公网安备 33010602011771号