在C++中如何仅将结构体成员变量转换为字节数组?
问题:如何提取含虚函数结构体中的成员变量部分转为字节数组
需求背景
我需要将包含成员变量和函数的结构体中仅成员变量部分转换为字节数组/vector,用于上传至Vulkan显卡。目标是让用户能轻松自定义参数结构体,无需关注底层转换逻辑。
现有实现方案
我通过一个带纯虚函数的空基类ParamsBase派生出实际参数结构体(如ParamsA、ParamsB),这样Container类可保存ParamsBase指针,无需知晓具体实现细节。为统一获取实际参数结构体的大小,我使用泛型子类GetSizeImpl实现getSize()函数,避免每个参数结构体都重写该方法。
完整代码实现
// ============================= // === Define Params structs === // ============================= struct ParamsBase { virtual size_t getSize() const noexcept = 0; }; struct ParamsA : public ParamsBase { float vec[3] = { 2.3f, 3.4f, 4.5f }; }; // =============================================================== // === enable sizeof query for derived structs from ParamsBase === // =============================================================== template<class T> struct GetSizeImpl : T { using T::T; size_t getSize() const noexcept final { return sizeof(T); } }; template<class T, class... Args> std::unique_ptr<T> create(Args&&... args) { return std::unique_ptr<T>(new GetSizeImpl<T>(std::forward<Args>(args)...)); } // ============ // === Util === // ============ template<typename T> std::vector<uint8_t> asByteVector(T* t, size_t size) { std::vector<uint8_t> byteVec; byteVec.reserve(size); uint8_t* dataArr = std::bit_cast<uint8_t*>(t); byteVec.insert(byteVec.end(), &dataArr[0], &dataArr[size]); return byteVec; } // ============================================ // === Use Params struct in container class === // ============================================ class Container { public: Container(ParamsBase* params) : Params(params) {} const std::vector<uint8_t>& getParamsAsBuffer() { ParamsAsBuffer = asByteVector(Params, Params->getSize()); return ParamsAsBuffer; } size_t getParamsSize() const { return Params->getSize(); } private: ParamsBase* Params = nullptr; std::vector<uint8_t> ParamsAsBuffer; };
问题现象
转换后的字节数组尺寸异常,且头部存在无效数据。通过对比纯数据结构体ParamsCompareA可清晰看到差异:
// ================================ // === Define comparison struct === // ================================ struct ParamsCompareA { float vec[3] = { 2.3f, 3.4f, 4.5f }; }; int main() { // create instances auto pA = create<ParamsA>(); Container cA(pA.get()); std::vector<uint8_t> vecA = cA.getParamsAsBuffer(); // comparison ParamsCompareA pcA; size_t sizeCompA = sizeof(ParamsCompareA); std::vector<uint8_t> compVecA = asByteVector(&pcA, sizeof(ParamsCompareA)); std::cout << "ParamsA size: " << std::to_string(pA->getSize()) << "; CompParamsA size: " << sizeof(ParamsCompareA) << std::endl; float* bufAf = reinterpret_cast<float*>(vecA.data()); float* bufCompAf = reinterpret_cast<float*>(compVecA.data()); }
compVecA为正常的12字节(对应3个float),转换为float后可得到正确值vecA却有24字节,实际有效数据位于第2到14字节区间内
我不想通过硬编码偏移量来解决问题,请问有没有合理的方法仅提取结构体中的成员变量部分?
内容的提问来源于stack exchange,提问作者Tare
相关产品推荐
相关产品推荐

