You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确将C++ DLL中的const char*转换为C#字符串?

C++ const char* 转 C# 字符串时字符乱码的问题分析与解决

问题根源

你的问题核心是编码不匹配和控制字符的错误解析:

  • C++中的const char*本质是单字节序列,而你传递的字符串包含ASCII控制字符(如\x2、\x3)。使用UnmanagedType.LPStr封送时,CLR会采用当前系统的ANSI代码页(比如Windows-1252)解码字节,而非纯ASCII标准。部分控制字符在ANSI代码页中会被错误映射为可打印字符(例如你遇到的\x2被解析为È)。
  • 尝试LPWStr完全错误,因为它对应C++的宽字符wchar_t*,和你传递的单字节const char*类型不兼容,必然导致乱码。

解决办法

1. 封送为IntPtr,手动按指定编码转换(最可靠)

避免直接封送为string,先把const char*转为IntPtr,再手动读取字节数组并按目标编码转换,确保控制字符和特殊字符都被正确解析:

修改C#委托定义:

private delegate void OnPlayerTextMessageReceivedCallback(
    IntPtr senderEntityIdPtr,
    IntPtr messagePtr
);

回调方法中处理字符串:

private void OnPlayerTextMessageReceived(IntPtr senderPtr, IntPtr messagePtr)
{
    // 方式1:直接用ANSI读取(依赖系统代码页,适合包含扩展ASCII字符如ß的场景)
    string sender = Marshal.PtrToStringAnsi(senderPtr);
    string message = Marshal.PtrToStringAnsi(messagePtr);

    // 方式2:手动读取字节数组,按明确编码转换(更严谨,适合控制字符多的场景)
    // List<byte> messageBytes = new List<byte>();
    // int offset = 0;
    // byte currentByte = Marshal.ReadByte(messagePtr, offset);
    // while (currentByte != 0)
    // {
    //     messageBytes.Add(currentByte);
    //     offset++;
    //     currentByte = Marshal.ReadByte(messagePtr, offset);
    // }
    // // 如果是纯ASCII用Encoding.ASCII,包含扩展字符用对应编码如Windows-1252
    // string message = Encoding.GetEncoding(1252).GetString(messageBytes.ToArray());
}

2. 明确指定解码编码

如果必须用string作为委托参数,需确保解码编码和C++端一致:

  • 若C++字符串是纯ASCII,在C#中封送后用Encoding.ASCII重新处理(但LPStr可能已经用系统代码页解析,所以还是手动转字节数组更可靠)。
  • 若包含扩展ASCII字符(如ß),用对应编码(比如Windows-1252)解码:
    byte[] messageBytes = Encoding.Default.GetBytes(message);
    string correctMessage = Encoding.GetEncoding(1252).GetString(messageBytes);
    

关键注意事项

  • 禁止混用单字节和宽字符封送:LPWStr和const char*类型不匹配,绝对不能使用。
  • 控制字符(如\x2、\x3)依赖固定编码解析,避免依赖系统默认ANSI代码页,否则不同系统会出现不同乱码。

内容的提问来源于stack exchange,提问作者JonRicardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:40:28