Как работать со структурами C с макетами, определяемыми во время выполнения? - PullRequest
0 голосов
/ 30 июля 2011

В моем коде мне нужно иметь дело с одной из двух структур, которые разделяют почти все элементы, но их смещения могут быть определены только во время выполнения.Что-то вроде:

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 ]

1 голос
/ 30 июля 2011

Если вы не можете изменить порядок, я бы объединил их в ту же структуру, что и объединение:

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;
}

Возможно, это не большое улучшение, но вы можете избежать приведения типов ...

0 голосов
/ 30 июля 2011

Переместите общие члены в отдельную структуру и используйте ее в качестве первого члена двух типов. Преимущество этого заключается в том, что вам не нужно тестировать типы (или даже заботиться о них) для чтения / записи общих данных.

#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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...