0

环境:

  • 虚幻引擎 5
  • 视窗 10
  • 协议缓冲区 v3.18.0

我正在尝试在Unreal Engine 5 (c++)中使用protoc. 如果消息包含小于 127 的 int var 值,则一切正常。但是如果值超过 127 我会发现错误:Failed to parse input.

player.proto:

syntax = "proto3";
package com.game;

message Player {
    string username = 1;
    int64 experience = 2;
}

成功案例

C++ 序列化并保存到文件:

com::game::Player MyPlayer;
MyPlayer.set_username("test user name");
MyPlayer.set_experience(127); // <-- PAY ATTENTION

// serialization
std::string MyPlayerString;
if(!MyPlayer.SerializeToString(&MyPlayerString))
{
    UE_LOG(LogGameInstance, Error, TEXT("Can't serialize MyPlayer to String"));
    return;
}
const FString MyPlayerFString(MyPlayerString.c_str());

// save to file
const FString File = *FPaths::Combine(FPaths::GameSourceDir(), FApp::GetProjectName(), TEXT("temp.dat"));
FFileHelper::SaveStringToFile(
    MyPlayerFString,
    *File,
    FFileHelper::EEncodingOptions::AutoDetect,
    &IFileManager::Get()
);

protoc --decode_raw < temp.dat

1: "test user name"
2: 127

失败案例

C++ 序列化并保存到文件:

...
MyPlayer.set_experience(128); // <-- PAY ATTENTION
...

protoc --decode_raw < temp.dat

Failed to parse input.

我想当我尝试转换时会出现问题std::string -> FString。有任何想法吗?

4

1 回答 1

1

我找到了解决方案。

我会把它留在这里,也许它会对某人有所帮助。我更改了实现以避免字符串转换。

前:

...

// serialization
std::string MyPlayerString;
if(!MyPlayer.SerializeToString(&MyPlayerString))
{
    UE_LOG(LogGameInstance, Error, TEXT("Can't serialize MyPlayer to String"));
    return;
}
const FString MyPlayerFString(MyPlayerString.c_str());

// save to file
const FString File = *FPaths::Combine(FPaths::GameSourceDir(), FApp::GetProjectName(), TEXT("temp.dat"));
FFileHelper::SaveStringToFile(
    MyPlayerFString,
    *File,
    FFileHelper::EEncodingOptions::AutoDetect,
    &IFileManager::Get()
);

后:

// serialization
const auto MyPlayerSize = MyPlayer.ByteSizeLong();
const auto MyPlayerBytes = new uint8[MyPlayerSize]();
if(!MyPlayer.SerializeToArray(MyPlayerBytes, MyPlayerSize))
{
    UE_LOG(LogGameInstance, Error, TEXT("Can't serialize MyPlayer to Array"));
    return;
}
TArray64<uint8>* MyPlayerArray = new TArray<uint8, FDefaultAllocator64>(MyPlayerBytes, MyPlayerSize);

// save to file
const FString File = *FPaths::Combine(FPaths::GameSourceDir(), FApp::GetProjectName(), TEXT("temp.dat"));
FFileHelper::SaveArrayToFile(
    *MyPlayerArray,
    *File,
    &IFileManager::Get()
);
于 2021-09-20T17:58:05.323 回答