You need to enable JavaScript to run this app. 在C++(Unreal)环境下实现BSON文件反序列化的方法咨询
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 13:39:03