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

Unreal Engine 5 C++中Protoc解析大于127的整数值时失败问题排查

解决UE5中Protobuf序列化二进制数据保存后解析失败的问题

你猜的完全正确!问题的核心就是把Protobuf的二进制序列化数据转成FString时的编码错误。下面我来拆解原因并给出完整的修复方案:

问题根源

Protobuf序列化出来的是纯二进制流,不是合法的UTF-8字符串:

  • 当整型值≤127时,Varint编码只需要1字节,刚好是ASCII范围内的字符,转FString时不会出问题;
  • 当值>127时(比如128),Varint会用多字节编码(128的编码是0x80 0x01),这些字节不属于合法UTF-8字符;
  • 你用FString(MyPlayerString.c_str())转换时,Unreal的FString会尝试把输入当作UTF-8解析,遇到无效字节会自动截断或替换,导致保存到文件的二进制数据已经损坏,protoc自然解析失败。

修复方案:用字节数组存储二进制数据

Unreal中处理二进制数据的标准方式是TArray<uint8>,它不会对内容做任何编码转换,能完整保留Protobuf的原始序列化结果。

修改后的序列化保存代码

com::game::Player MyPlayer;
MyPlayer.set_username("test user name");
MyPlayer.set_experience(128); // 现在设为128也没问题了

// 序列化到std::string(注意:std::string在这里只是二进制容器,不是字符串)
std::string MyPlayerBytes;
if(!MyPlayer.SerializeToString(&MyPlayerBytes)) {
    UE_LOG(LogGameInstance, Error, TEXT("Can't serialize MyPlayer to bytes"));
    return;
}

// 转换为Unreal的字节数组,完整保留所有二进制数据
TArray<uint8> PlayerData;
PlayerData.Append((const uint8*)MyPlayerBytes.data(), MyPlayerBytes.size());

// 保存到文件,直接用二进制模式保存字节数组
const FString File = *FPaths::Combine(FPaths::GameSourceDir(), FApp::GetProjectName(), TEXT("temp.dat"));
if (!FFileHelper::SaveArrayToFile(PlayerData, *File)) {
    UE_LOG(LogGameInstance, Error, TEXT("Failed to save player data to file"));
}

验证结果

运行修改后的代码后,执行命令:

protoc --decode_raw < temp.dat

会得到正确的输出:

1: "test user name"
2: 128

额外提示

如果之后需要从文件读取数据并解码,也要用FFileHelper::LoadFileToArray读取成TArray<uint8>,再转成std::string给Protobuf解码,避免同样的编码问题:

TArray<uint8> LoadedData;
if (FFileHelper::LoadFileToArray(LoadedData, *File)) {
    std::string LoadedBytes((const char*)LoadedData.GetData(), LoadedData.Num());
    com::game::Player LoadedPlayer;
    if (LoadedPlayer.ParseFromString(LoadedBytes)) {
        // 解码成功,处理数据
        UE_LOG(LogGameInstance, Log, TEXT("Loaded player: %s, exp: %lld"), *FString(LoadedPlayer.username().c_str()), LoadedPlayer.experience());
    }
}

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

火山引擎 最新活动