在C++(Unreal)环境下实现BSON文件反序列化的方法咨询
Unreal C++ 基于libbson的BSON文件反序列化实现
你可以按照以下步骤直接改写C#逻辑到Unreal C++环境:
1. 首先定义对应的数据结构
和C#的类对应,你需要先定义SampleClass和Databases结构,这里默认你C#的SampleClass包含_date时间字段,Unreal侧用引擎原生的FDateTime处理时间:
// 对应C#的SampleClass struct FSampleClass { FDateTime _date; // 其他SampleClass的字段按需添加 }; // 对应C#的Databases类 struct FDatabases { TMap<FString, FSampleClass> _databases; };
2. 实现反序列化核心逻辑
libbson没有C#那样的自动反射序列化能力,需要手动读取BSON字段映射到C++结构,完整实现代码如下:
#include "Misc/FileHelper.h" #include "Misc/Paths.h" #include "GenericPlatform/GenericPlatformFile.h" #include "libbson/include/bson.h" void ProcessBsonFiles() { // 对应C#的获取程序集目录,这里用Unreal的二进制目录,你可以按需换成你要扫描的目录 FString ScanDir = FPaths::ProjectBinariesDir(); TArray<FString> BsonFiles; // 扫描目录下所有.bson文件 IFileManager::Get().FindFiles(BsonFiles, *ScanDir, TEXT(".bson")); for (const FString& FilePath : BsonFiles) { FString FullPath = ScanDir / FilePath; TArray<uint8> FileContent; // 读取BSON文件所有字节,对应C#的File.ReadAllBytes if (!FFileHelper::LoadFileToArray(FileContent, *FullPath)) { UE_LOG(LogTemp, Warning, TEXT("读取文件失败:%s"), *FullPath); continue; } // 初始化libbson的bson对象 bson_t* BsonObj = bson_new_from_data(FileContent.GetData(), FileContent.Num()); if (!BsonObj) { UE_LOG(LogTemp, Warning, TEXT("BSON解析失败:%s"), *FullPath); continue; } FDatabases Result; bson_iter_t Iter; bson_iter_t DbIter; // 读取顶层的_databases字段 if (bson_iter_init_find(&Iter, BsonObj, "_databases") && BSON_ITER_HOLDS_DOCUMENT(&Iter)) { const uint8_t* DocData = nullptr; uint32_t DocLen = 0; bson_iter_document(&Iter, &DocLen, &DocData); bson_t* DbDoc = bson_new_from_data(DocData, DocLen); if (DbDoc && bson_iter_init(&DbIter, DbDoc)) { // 遍历_databases下的所有键值对,对应C#的Dictionary<string, SampleClass> while (bson_iter_next(&DbIter)) { const char* Key = bson_iter_key(&DbIter); FString CppKey = UTF8_TO_TCHAR(Key); FSampleClass Sample; // 读取SampleClass里的_date字段,BSON的时间字段是BSON_TYPE_DATE_TIME bson_iter_t SampleIter; if (bson_iter_recurse(&DbIter, &SampleIter) && bson_iter_find(&SampleIter, "_date") && BSON_ITER_HOLDS_DATE_TIME(&SampleIter)) { int64_t TimestampMs = bson_iter_date_time(&SampleIter); // BSON时间是毫秒级Unix时间戳,转Unreal的FDateTime Sample._date = FDateTime::FromUnixTimestampMilliseconds(TimestampMs); } // 其他SampleClass字段按需在这里添加读取逻辑 Result._databases.Add(CppKey, Sample); } } bson_destroy(DbDoc); } // 对应C#的输出"001"对应的date if (Result._databases.Contains(TEXT("001"))) { UE_LOG(LogTemp, Log, TEXT("001对应的日期:%s"), *Result._databases[TEXT("001")]._date.ToString()); } // 释放libbson内存,避免泄漏 bson_destroy(BsonObj); } }
3. 注意事项
- 如果你
SampleClass有其他字段,按照上面的_date读取逻辑,对应libbson的类型判断接口读取即可,常用类型对应:BSON_TYPE_INT32/BSON_TYPE_DOUBLE/BSON_TYPE_UTF8(字符串)/BSON_TYPE_BOOL - Unreal的字符串和libbson的UTF8字符串转换用
UTF8_TO_TCHAR和TCHAR_TO_UTF8即可 - 所有通过
bson_new_from_data创建的bson_t对象必须调用bson_destroy释放,否则会出现内存泄漏
内容的提问来源于stack exchange,提问作者mirkojpn
相关产品推荐
相关产品推荐

