Структуры двух разных типов - необходимо динамически передавать один из них в функцию - PullRequest
0 голосов
/ 24 октября 2018

Заранее извиняюсь, я только начал писать C 2 месяца назад, так что для меня все это довольно ново.

Я работаю над базой кода, в которой уже реализовано решение, которое необходимо изменить.

В настоящее время одна структура содержит все переменные для функций чтения и записи.Это должно быть изменено, чтобы быть двумя различными структурами, одна для чтения, другая для записи.

Ниже приведена текущая реализация.

typedef struct Foo_s
{
 int x;
 int y;
 int z;
}

BarFunction(Foo_s foo) {
 //logic
}

Вот изменения, которые мне нужно сделать

typedef struct FooRead_s
{
 int x;
 int y;
}

typedef struct FooWrite_s
{
 int z;
}

Проблема возникает при вызове BarFunction(Foo_s foo).Он должен быть в состоянии принять либо FooRead_s, либо FooWrite_s в любой момент времени, даже если они разные.Как мне разрешить BarFunction принять FooRead_s и FooWrite_s?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Если мы исправим ваши typedefs и напишем функцию для принятия структуры, переданной указателем, как это должно быть спроектировано, то мы получим следующее:

typedef struct 
{
  int x;
  int y;
} FooRead_s;

typedef struct 
{
  int z;
} FooWrite_s;

void BarFunction_Read (FooRead_s* foo) {
 //logic
}

void BarFunction_Write (FooWrite_s* foo) {
 //logic
}

Теперь, если у вас есть возможностьиспользуя стандартный язык C, вы можете написать вызов функции с помощью общего программирования:

#define BarFunction(foo)                    \
  _Generic((foo),                           \
           FooRead_s*:  BarFunction_Read,   \
           FooWrite_s*: BarFunction_Write)(foo)

int main (void)
{
  FooRead_s read = {0};
  FooWrite_s write = {0};

  BarFunction(&read);
  BarFunction(&write);
  //BarFunction(read); compiler error here as we should have
}
0 голосов
/ 24 октября 2018

В C нет способа различить две или более структур без какого-либо параметра селектора.Можно использовать объединение структур FooRead_s, FooWrite_s и селектор операций.Селектор может быть передан как отдельный аргумент

typedef union {
    FooRead_s rs;
    FooWrite_s ws;
} Foo_params;

void BarFunction(bool write, Foo_params *foo) {
     if (write) {
         // use foo->ws;
     }
     // ...
}

или встроен в структуру

typedef struct {
    bool write;
    union {
        FooRead_s rs;
        FooWrite_s ws;
    } params;
} Foo_action;

void BarFunction(Foo_action *foo) {
     if (foo->write) {
         // use foo->params.ws;
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...