简体   繁体   English

是否有符合标准的方法来指定 C++ 中的字段偏移量?

[英]Is there a standard-compliant way to specify field offsets in C++?

I have a chunk of memory populated by external code which I'm trying to reverse engineer.我有一大块内存由我试图逆向工程的外部代码填充。 I don't know the complete structure of this memory, but I do know a few fields (eg the chunk starts off with an int32 named 'foo' and there's a double at offset 0xC called 'bar').我不知道这个内存的完整结构,但我知道一些字段(例如,块以一个名为“foo”的 int32 开头,并且在偏移量 0xC 处有一个名为“bar”的双精度值)。 I want to define a structure and essentially reinterpret-cast a pointer to this memory chunk to that structure, and have it line up.我想定义一个结构,并基本上将指向该内存块的指针重新解释为该结构,并将其对齐。 I'm not sure if there's a more conventional name for this technique but I'll refer to it as creating an 'overlay type'.我不确定这种技术是否有更传统的名称,但我将其称为创建“覆盖类型”。

Here's a sketch of what I'd like to be able to do:这是我希望能够做的事情的草图:

START_OVERLAY_TYPE(my_type, 0xFF) // struct named my_type, size 0xFF
    FIELD(0x00, int32_t foo);     // field int32_t foo at 0x00
    FIELD(0x0C, double bar);      // field double bar at 0x0C
END_OVERLAY_TYPE

Not having to use macros would be a plus, but I don't see a good way around them.不必使用宏将是一个加分项,但我没有看到解决它们的好方法。

With my current implementation, I expand this to (something like):在我当前的实现中,我将其扩展为(类似):

__pragma(pack(push, 1))
template<size_t p> struct padding_t { unsigned char pad[p]; };
template<> struct padding_t<0> {};
struct my_type
{
    union
    {
        struct : padding_t<0xFF> {}; // ensure total size is 0xFF
        struct : padding_t<0x00> { int32_t foo; }; // field at 0x00
        struct : padding_t<0x0C> { double bar; }; // field at 0x0C
    };
};
__pragma(pack(pop))

This compiles and works great, at least in the versions I tried of clang, gcc, and VC++ (with appropriate changes to the pragma).这编译并运行良好,至少在我尝试的 clang、gcc 和 VC++ 版本中(对 pragma 进行了适当的更改)。 Unfortunately, warnings abound due to the non-standard use of anonymous structs.不幸的是,由于匿名结构的非标准使用,警告比比皆是。

Is there any way to achieve the same effect while staying within the standard?有什么方法可以在保持标准的同时达到相同的效果吗? The requirements are that it be reasonably simple to declare (like the current macro is), and that to the consumer, the usage is indistinguishable from要求是声明相当简单(就像当前的宏一样),并且对于消费者来说,用法与

struct my_type { int32_t foo; double bar; }

at least to the casual observer.至少对于不经意的观察者来说。

The current code will work for my purposes, I'm just curious if there is a better approach I am overlooking.当前的代码将适用于我的目的,我只是好奇是否有更好的方法可以忽略。

You could try something like this with implicit type conversions and assignment operators for the internal struct containing the value.对于包含值的内部结构,您可以尝试使用隐式类型转换和赋值运算符进行类似的操作。 This way instead of using unnamed structs the struct bears the name, but the internals become the unnamed part through operator overloading.这种方式不是使用未命名的结构,而是结构带有名称,但内部结构通过运算符重载成为未命名的部分。

I tried this out with some client code (passing to functions, getting/setting values) and everything seemed fine.我用一些客户端代码(传递给函数,获取/设置值)尝试了这个,一切似乎都很好。 It's of course possible that I missed a scenario somewhere.我当然有可能在某处错过了一个场景。

__pragma(pack(push, 1))
template<size_t p, typename t>
struct padding_t
{
    unsigned char pad[p];
    t             val;
    operator t  () const {return val;}
    operator t& ()       {return val;}
    padding_t<p, t>& operator= (const t& rhs) {val = rhs; return *this;}
};
template<typename t> struct padding_t<0, t>
{
    t             val;
    operator t  () const {return val;}
    operator t& ()       {return val;}
    padding_t<0, t>& operator= (const t& rhs) {val = rhs; return *this;}
};
template<size_t p>
struct sizing_t
{
    unsigned char pad[p];
};
struct my_type
{
    union
    {
        sizing_t<0xFF>           size; // ensure total size is 0xFF
        padding_t<0x00, int32_t> foo;  // field at 0x00
        padding_t<0x0C, double>  bar;  // field at 0x0C
    };
};
__pragma(pack(pop))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否有符合 C++ 标准的方法来获取对协程 promise 的已知基数 class 的引用? - Is there a C++ standard-compliant way to obtain a reference to a known base class of a coroutine promise? 以符合C ++标准的方式实现std :: malloc - Implementing std::malloc in a C++ standard-compliant manner 符合标准的方法来定义浮点等价关系 - Standard-compliant way to define a floating-point equivalence relationship 是否有符合标准的方法来确定非静态成员的对齐方式? - Is there a standard-compliant way to determine the alignment of a non-static member? 最有效的符合标准的方法,将int重新解释为float - Most efficient standard-compliant way of reinterpreting int as float 是否有一种可移植/符合标准的方法来获取堆栈跟踪中的文件名和行号? - Is there a portable/standard-compliant way to get filenames and linenumbers in a stack trace? 访问整数类型数组的安全和符合标准的方法作为另一个不相关的整数类型的数组? - The safe and standard-compliant way of accessing array of integral type as an array of another unrelated integral type? 如何以符合标准的方式实现C ++插件? - How to implement a C++ plugin in a standard compliant way? 成功地编译格式错误的程序是否符合标准? - Is it standard-compliant to compile ill-formed program in success? 一种安全,符合标准的方法,只有在实例化了static_assert的情况下,才能使类模板专业化而无法编译? - A safe, standard-compliant way to make a class template specialization fail to compile using `static_assert` only if it is instantiated?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM