0

I'm trying to process structures which are contained in a file mapping. One of the challenges I'm facing is that some structures have pointers which need a function to get the correct value. It's important that the layout and size of the structure stay the same, and I'm using c++20.

My current solution is as follows. I have a private data structure, and store the member offsets in a public subclass. The template factory method uses this array of offsets to fix up any pointers.

struct _Data {
    uint32_t flags;
    uint64_t ptr1;
    uint64_t ptr2;
};

struct Data : public {
    constexpr static std::size_t PTRS[] = {
        offsetof(_Data, ptr1),
        offsetof(_Data, ptr2)
    };
};

template <class T> T GetStructure(uint64_t addr) {
    // Converts the "virtual address" to a pointer in the file mapping
    T temp = *(T *)context.translateAddr(addr);

    for (auto offset : T::PTRS) {
        uint64_t *member = (uint8_t *)temp + offset;
        *member = context.getPointer(addr + offset);
    }
    return temp;
}

I found a similar question here dealing with serialization, which also stores metadata about members in a list.

My main gripe with my solution is how I need to split a definition into two structures. It would be great if I could contain everything within its own definition.

Other solutions I thought were,

  • Somehow "mark" a member in a way the factory method can detect.
  • Using a function to return a vector of offsets. This would solve the two definitions problem, but I'm concerned about the performance of constantly calling a function and return a vector.
  • Using a constexpr function to return a std::array. Faster than returning a vector for sure, but probably slower than a constexpr list like the one shown above.
  • I can make a separate templated function which returns a a vector of offsets given the structure, but this seems to combine worst of both worlds.
ArandomDev
  • 125
  • 2
  • 10

0 Answers0