如果 Unreal Engine 5 c++ 中的整数值超过 127,Protoc 无法解析输入
Protoc failed to parse input if integer value more than 127 in Unreal Engine 5 c++
环境:
- Unreal Engine 5
- Windows 10
- 协议缓冲区 v3.18.0
我正在尝试使用 protoc
解码 Unreal Engine 5 (c++) 中的序列化数据。如果消息包含小于 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()
);
协议 --decode_raw < temp.dat
1: "test user name"
2: 127
失败案例
C++序列化并保存到文件:
...
MyPlayer.set_experience(128); // <-- PAY ATTENTION
...
协议 --decode_raw < temp.dat
Failed to parse input.
我想我尝试转换 std::string -> FString
时出现了问题。有什么想法吗?
我找到了解决方法。
我会把它留在这里,也许它会对某人有所帮助。
我更改了实现以避免字符串转换。
之前:
...
// 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()
);
环境:
- Unreal Engine 5
- Windows 10
- 协议缓冲区 v3.18.0
我正在尝试使用 protoc
解码 Unreal Engine 5 (c++) 中的序列化数据。如果消息包含小于 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()
);
协议 --decode_raw < temp.dat
1: "test user name"
2: 127
失败案例
C++序列化并保存到文件:
...
MyPlayer.set_experience(128); // <-- PAY ATTENTION
...
协议 --decode_raw < temp.dat
Failed to parse input.
我想我尝试转换 std::string -> FString
时出现了问题。有什么想法吗?
我找到了解决方法。
我会把它留在这里,也许它会对某人有所帮助。 我更改了实现以避免字符串转换。
之前:
...
// 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()
);