Вызов функции обратного вызова C с предоставленными аргументами Variadi c дает странный результат - PullRequest
0 голосов
/ 08 мая 2020

В приведенном ниже коде параметры типа float или double не работают, значение всегда неверно. int и строки работают должным образом.

Я собираюсь отказаться от этой конструкции и попробовать что-нибудь еще, если кто-то не обнаружит проблему.

typedef void(*varfunc)(...);
typedef void(*invokefunc)(int, ...);

varfunc func_table[2];

void register_func(int slot, varfunc cb)
{
    func_table[slot] = cb;
}

void invoke_func(int slot, void* a1, void* a2, void* a3, void* a4)
{
    func_table[slot](a1, a2, a3, a4);
}

void func_1(float a, int b)
{
    printf("%f %d", a, b);
}

void func_2(const char* c)
{
    printf("%s", c);
}


int main()
{
    register_func(0, (varfunc)func_1);
    register_func(1, (varfunc)func_2);

    ((invokefunc)invoke_func)(0, 1.23f, 456);
    ((invokefunc)invoke_func)(1, "hello world");

    return 0;
}

1 Ответ

0 голосов
/ 08 мая 2020

В предоставленном вами коде вы указываете аргументы для invoke_func как указатели void, которые могут иметь размеры, отличные от чисел с плавающей запятой или целых чисел, и, как таковые, будут вызывать неопределенное поведение при передаче их в func_1. Я изменил func_1 следующим образом:

void func_1(float* a, int* b)
{
    printf("%f %d", *a, *b);
}

И теперь вы можете вызвать его с помощью:

float a = 1.23f;
int b = 456;

((invokefunc)invoke_func)(0, &a, &b);

Это успешно работает на моей машине.

...