Правильное использование Callback для одной и той же операции и другого типа - PullRequest
0 голосов
/ 06 сентября 2018

Я занимаюсь разработкой на C, и мне нужно спросить информацию об использовании обратного вызова.

Предположим, я определил 3 обратных вызова с 3 различными типами ввода для обратного вызова, пример:

typedef void (*CB_1) (const struct paramType_1 *p);
typedef void (*CB_2) (const struct paramType_2 *p);
typedef void (*CB_3) (const struct paramType_3 *p);

Хорошо, у меня есть 3 массива обратных вызовов, каждый для типа обратного вызова:

static CB_1         CB1List[10] ;
static CB_2         CB2List[10] ;
static CB_3         CB3List[10] ;

Итак, я определил 3 списка обратных вызовов для вызова (в разных ситуациях), и каждый список имеет определенный тип обратного вызова (CB_1, CB_2 или CB_3), который имеет определенный параметр обратного вызова (paramType_1, paramType_2 или paramType_3).

Предположим теперь, что мне нужно выполнить операцию, которая является ИДЕНТИЧНОЙ для каждого обратного вызова ... Я должен скопировать вставить 3 раза функцию из-за различных конкретных параметров ... предположим, например, что мне нужно добавить обратный вызов в массив мне нужно это;:

   static void CBAdd_1(CB_1 _cb) {   
      CB1List[i] = _cb
    }
   static void CBAdd_2(CB_2 _cb) {   
      CB2List[i] = _cb
    }
    static void CBAdd_3(CB_3 _cb) {  
      CB3List[i] = _cb
    }

Как правильно использовать универсальную функцию "void CBAdd", чтобы не повторять трижды функцию для трех обратных вызовов? возможно, используя (void *) параметры или другие?

спасибо

1 Ответ

0 голосов
/ 06 сентября 2018

Да, вам нужен параметр void *, как показано ниже. В качестве альтернативы (зависит от ваших потребностей) вы можете использовать объединение вместо struct и хранить все члены в этом единственном типе объединения. Имея это, параметр типа объединения будет передан всем функциям, и определение функции может решить, какой элемент использовать.

#include <stdio.h>

typedef struct paramType_1
{
  int p;
} paramType_1;

typedef struct paramType_2
{
  int p;
} paramType_2;

typedef struct paramType_3
{
  int p;
} paramType_3;

typedef void (*CB) (const void* p);

static CB CBList[10];

void CB_1(const void* p)
{
  const paramType_1* pt = (paramType_1*)p;
  printf("p1: %d\n", pt->p);
}

void CB_2(const void* p)
{
  const paramType_2* pt = (paramType_2*)p;
  printf("p2: %d\n", pt->p);
}

void CB_3(const void *p)
{
  const paramType_3* pt = (paramType_3*)p;
  printf("p3: %d\n", pt->p);
}

static int c = 0;

static void CBAdd(CB cb_)
{
  CBList[c++] = cb_;
}

int main()
{
  int i = 0;
  paramType_1 p1;
  paramType_2 p2;
  paramType_3 p3;

  for (i = 0; i < 3; i++)
  {
    CBAdd(CB_1);
  }

  for (i = 0; i < 3; i++)
  {
    CBAdd(CB_2);
  }

  for (i = 0; i < 3; i++)
  {
    CBAdd(CB_3);
  }

  p1.p = 1;
  p2.p = 2;
  p3.p = 3;

  for (i = 0; i < 3; i++)
  {
    (CBList[i])((void*)&p1);
  }

  for (i = 3; i < 6; i++)
  {
    (CBList[i])((void*)&p2);
  }

  for (i = 6; i < 9; i++)
  {
    (CBList[i])((void*)&p3);
  }

  return 0;
}
...