如何在 32 位和 64 位机器的头文件中获得相同的结构?

发布于 2025-01-07 23:57:05 字数 155 浏览 3 评论 0原文

我有一个对于 32 位和 64 位机器应该具有相同形状(至少大小相同,我认为偏移量会随之而来)的结构。

我们的结构是一个混淆的类型,大小是在构建时生成的,我们无法知道该类型是否会在 32 ou 64 位架构上使用。

这样做的最佳做法是什么?你有这样做的项目指针吗?

I have a structure which should have the same shape (at least same size, offsets will come with it I think) for 32 and 64 bits machines.

Our struct is an obfuscated type, the size is generated at build time, and we can't know if this type will be used on 32 ou 64 bit arch.

What is the best practice to do that? Do you have pointers of project doing so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野却迷人 2025-01-14 23:57:06

如果我理解正确的话,您想要生成一个结构,该结构在 32 位系统上应具有与 64 位系统上完全相同的布局。

例如,假设您将生成以下结构:

struct S
   {
   long l;
   char *s;
   int i;
   long l2;
   };

那么这在 64 位上将具有与 32 位上不同的布局(在这种情况下,字符指针将具有不同的大小)。
如果您在旧的 DOS 系统上编译它,那么 int 将是 16 位而不是 32 位,并且您将再次拥有不同的布局。

解决这个问题的最佳方法是定义您自己的类型,并在您的结构中使用它们,如下所示:

typedef long  MY_INT4;
typedef short MY_INT2;

然后在您的结构中使用这些类型。
如果您需要移植到不同的系统,您只需要检查您的 typedef。

struct S
   {
   MY_INT4 m1;
   MY_INT2 m2;
   };

对于某些类型(例如指针),这个技巧不起作用,因为没有适用于 32 位或 64 位指针的内置类型,所有指针都是相似的(如果我们忘记了旧的 DOS 远近) - 指针)。

对于这些类型,您可以使用宏。例如这样:

struct S
   {
   MY_INT4 m1;
   MY_INT2 m2;
   MY_POINTER(char,m3);
   };

那么对于 64 位系统你只需要像这样定义 MY_POINTER:

#define MY_POINTER(t,m) t *m

对于 32 位系统你可以这样定义它:

#define MY_POINTER(t,m) t *m; t *dummy

所以对于 32 位系统我们添加 2 个指针字段而不是 1 个

。最后一种方法是,当您有 2 个指针时,这些宏将生成 2 个具有相同名称的成员。

您可以通过使用未命名的联合来解决此问题。像这样定义你的宏:

#define MY_POINTER(t,m) t *m; union {t *dummy;}

请注意,使用这个解决方案我忽略了字节排序的问题。如果你想解决这个问题,你需要更深入地研究。

If I understand correctly you want to generate a struct which should have exactly the same layout on a 32-bit as on a 64-bit system.

E.g. suppose that you would generate this struct:

struct S
   {
   long l;
   char *s;
   int i;
   long l2;
   };

Then this will have a different layout on 64-bit as on 32-bit (the char-pointer will have a different size in this case).
If you would compile this on an old DOS system, then int would be 16-bit instead of 32-bit and you would have again a different layout.

The best way to tackle this is to define your own types, and use these in your structure, like this:

typedef long  MY_INT4;
typedef short MY_INT2;

Then use these types in your struct.
If you ever need to port to a different system, you only need to review your typedefs.

struct S
   {
   MY_INT4 m1;
   MY_INT2 m2;
   };

For some types (like for pointers), this trick doesn't work since there is no built-in type for 32-bit or for 64-bit pointers, all pointers are alike (if we forget about the old DOS far- and near-pointers).

For those types, you could use macro's. E.g. this:

struct S
   {
   MY_INT4 m1;
   MY_INT2 m2;
   MY_POINTER(char,m3);
   };

Then for 64-bit systems you only need to define MY_POINTER like this:

#define MY_POINTER(t,m) t *m

For 32-bit systems you can define it like this:

#define MY_POINTER(t,m) t *m; t *dummy

So for 32-bit systems we add 2 pointer-fields instead of 1.

The problem with this last approach is that when you have 2 pointers, these macro's will generate 2 members with the same name.

You can solve this problem by using an unnamed union. Define your macro like this:

#define MY_POINTER(t,m) t *m; union {t *dummy;}

Notice that with this solution I ignored the problem of byte-ordering. If you want to solve that you need to dive deeper.

南城旧梦 2025-01-14 23:57:06

我有一个结构,对于 32 位和 64 位机器应该具有相同的形状(至少相同的大小,我认为偏移量会随之而来)。

技术上可行,但在实践中并未使用。

我们的结构是一个混淆类型,大小是在构建时生成的,我们无法知道该类型是否会在 32 ou 64 位架构上使用。
这样做的最佳做法是什么?您是否有这样做的项目指针

处理此问题的标准方法是为 32 位和 64 位平台使用相同的头文件并且有两个版本的库。标头的 32 位客户端链接到 32 位库,同样适用于 64 位库

。如果最终 32 位结构的对象需要进入 64 位代码(反之亦然),则必须有一个执行转换的代码段。这就是 32 位 glibc 在 64 位内核上的工作方式。

进行转换的一种简单而缓慢的方法是在文本中序列化并反序列化回来。

I have a structure which should have the same shape (at least same size, offsets will come with it I think) for 32 and 64 bits machines.

Technically possible, but not used in practice.

Our struct is an obfuscated type, the size is generated at build time, and we can't know if this type will be used on 32 ou 64 bit arch.
What is the best practice to do that? Do you have pointers of project doing so

Standard way of dealing with this issue is to have the same header file for both 32- and 64-bit platforms and have two builds of your library. A 32-bit client of your header links against a 32-bit library, same goes for 64.

If eventually an object of a 32-bit structure needs to get into a 64-bit code (or vice versa) there is must be a piece of code that does the conversion. This is how 32-bit glibc works on a 64-bit kernel.

A simple slow way of doing the conversion is to serialize in text and deserialize back.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文