如何使用运行时确定的布局处理C结构?

时间:2011-07-30 08:13:18

标签: c

在我的代码中,我需要处理几乎所有成员共享的两个结构中的一个,但它们的偏移量只能在运行时确定。 类似的东西:

struct type1 {int a, char b[8], int c};
struct type2 {int a, char b[16], int c};

关于这些结构的布局,我无能为力,因为它是由硬件决定的。

因此,每次我想访问某个成员时,我都需要执行以下操作:

void foo(void *data)
{
     if (is_type1)
         ((struct type1 *)(data))->c = 5;
     else
         ((struct type2 *)(data))->c = 5;
}

这不是很优雅。

我想知道是否有一些方法可以更好地处理这种情况,除了在宏中隐藏所有这些丑陋之外,这是我将在没有更好的情况下采用的解决方案。

感谢。

2 个答案:

答案 0 :(得分:1)

如果您无法更改订单,我会将它们加入到与union相同的结构中:

struct type12 { union { struct type1 type1; struct type2 type2; } types; int type; };

void foo(struct type12 *data)
{
    if (data->type == 1)
         data->types.type1.c = 5
    else
         data->types.type2.c = 5;
}

也许不是一个很大的改进,但你可以避免类型演员...

答案 1 :(得分:0)

将共享成员移动到单独的结构中,并将其用作这两种类型的第一个成员。这样做的好处是,您无需测试类型(甚至关心它们)来读取/写入共享数据。

#include <stdio.h>      
struct shared_data {
  int a;
  int c;
};
struct type1 {
  struct shared_data shared;
  char b[2];
};
struct type2 {
  struct shared_data shared;
  char b[4];
};

void foo(void *data)
{
     ((struct shared_data*)(data))->c = 5;
}    

int main(int argc, char** argv) {
    struct type1 a;
    struct type2 b;

    foo(&a);
    foo(&b);

    printf("A: %d\nB: %d\n", a.shared.c, b.shared.c);
}

输出

A: 5
B: 5