You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用C#序列化含Unicode与非Unicode字符串并实现C++反序列化

C# 序列化混合Unicode/非Unicode字符串适配C++反序列化方案

我之前刚好处理过类似的跨语言序列化场景,结合你提到的C++端核心逻辑(将非Unicode字符转成对应Unicode等价形式,统一序列化Unicode字符串),给你一套能完美适配的C#实现方案,保证两端兼容性:

核心对齐思路

首先要明确:C#中的string本身就是基于UTF-16的Unicode字符串,所以核心任务不是“转换”,而是确保输入字符串的所有字符都对应正确的Unicode码点,然后按照和C++端一致的二进制格式写入文件。

如果你的输入字符串来自非Unicode编码的数据源(比如GB2312、ISO-8859-1的字节流),第一步要做的是用对应的编码将字节解码成标准的UTF-16字符串;如果字符串已经是C#原生的string(不管混合了什么字符),那直接进入序列化步骤即可。

C# 序列化实现代码

下面是完整的序列化方法,包含预处理和写入逻辑,注释里标注了和C++端对齐的关键点:

using System.IO;
using System.Text;

public static class StringSerializer
{
    public static void SerializeToBinary(string inputString, string outputFilePath)
    {
        // 1. 预处理:如果输入来自非Unicode数据源,先解码为UTF-16字符串
        // 示例:如果原数据是ISO-8859-1编码的字节,先解码
        // byte[] rawBytes = File.ReadAllBytes("non-unicode-source.txt");
        // string inputString = Encoding.GetEncoding("ISO-8859-1").GetString(rawBytes);

        // 2. 将UTF-16字符串转换为字节数组(使用UTF-16LE,和Windows平台C++的wchar_t对齐)
        byte[] unicodeBytes = Encoding.Unicode.GetBytes(inputString);

        // 3. 写入文件:先写字符串长度(字符数,和C++端读取逻辑一致),再写字节流
        using (FileStream fs = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write))
        using (BinaryWriter writer = new BinaryWriter(fs, Encoding.Unicode))
        {
            // 写入字符数(注意:如果C++端是按字节数读取,这里要改成unicodeBytes.Length)
            writer.Write(inputString.Length);
            // 写入UTF-16LE字节
            writer.Write(unicodeBytes);
        }
    }
}

和C++反序列化的适配要点

  1. 编码对齐:C#中Encoding.Unicode对应UTF-16LE,这和Windows平台下Cwchar_t(16位小端)完全匹配,确保C端读取后能直接解析为std::wstring
  2. 长度标识:代码中写入的是字符串的字符数,如果你的C端是按字节数读取,把writer.Write(inputString.Length)改成writer.Write(unicodeBytes.Length)即可,必须和C端的读取逻辑严格一致。
  3. 非Unicode字符处理:如果C++端是把ISO-8859-1这类单字节编码的字符转成对应Unicode码点(比如0xC9 → U+00C9),C#中只要用对应编码解码原字节,就能得到完全一致的Unicode字符,不需要额外转换。

测试验证建议

你可以用一个混合字符的字符串做测试,比如:

string testString = "中文测试 Ééññ"; // 包含Unicode中文和ISO-8859-1的特殊字符
StringSerializer.SerializeToBinary(testString, "test.bin");

然后用你的C++反序列化器读取test.bin,应该能得到完全一致的字符串。

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

火山引擎 最新活动