【问题标题】:How to access elements of an array of function pointers passed to a function by a void pointer?如何访问通过 void 指针传递给函数的函数指针数组的元素?
【发布时间】:2023-02-25 00:05:53
【问题描述】:

我试图通过 void 指针将函数指针数组传递给函数。我不知道如何在传递给它们的函数中访问数组的元素。

示例 1 - 通过 void 指针传递常规数组:

#include <stdio.h>

void function(void* ptr)
{
    int* arr = ptr;

    for(int i = 0; i < 5; ++i)
    {
        printf("%d ", arr[i]);
    }
}

int main()
{
    int arr_nums[5] = { 1, 2, 3, 4, 5 };

    function((void*)arr_nums);

    return 0;
}

输出: 1 2 3 4 5

示例 2 - 通过 void 指针传递函数:

#include <stdio.h>

int add(int a, int b)
{
    return (a + b);
}

int sub(int a, int b)
{
    return (a - b);
}

int mult(int a, int b)
{
    return (a * b);
}

int divide(int a, int b)
{
    return (a / b);
}

int function(void *ptr)
{
    return ((int(*)(int, int))ptr)(4, 2);
}

int main()
{
    printf("%d\n, function((void*)add));
    printf("%d\n, function((void*)sub));
    printf("%d\n, function((void*)mult));
    printf("%d\n, function((void*)divide));

    return 0;
}

输出:

6
2
8
2

示例 3 - 将加法、减法、乘法和除法更改为函数指针数组:

...

int main()
{
    int (* fp_arr[4])(int, int) = { add, sub, mult, divide };
    
    printf("%d\n", function((void*)fp_arr[0]));
    printf("%d\n", function((void*)fp_arr[1]));
    printf("%d\n", function((void*)fp_arr[2]));
    printf("%d\n", function((void*)fp_arr[3]));
    
    return 0;
}

输出:

6
2
8
2

问题 - 尝试发送整个函数指针数组并访问函数内部的元素:

...
int function(void *ptr)
{
    return ((int(*)(int, int))ptr)(4, 2); <--- How to say something like ptr[2], would call mult
}

int main()
{
    int (* fp_arr[4])(int, int) = { add, sub, mult, divide };
    
    printf("%d\n", function((void*)fp_arr));
    
    return 0;
}

编辑:我遗漏了一些细节,因为我只是试图概述问题本身,我将函数指针数组传递给的函数来自图形库,因此我无法将参数类型从 void* 更改为其他类型。尽管我同意创建一个 typedef 别名。该库本身是 LVGL,但本质上我向一个对象添加了一个回调函数,该对象在具有一些用户数据的事件上触发。

即 - lv_obj_add_event_cb(obj, callback_fn, my_event_trigger, user_data); 用户数据将是我的函数指针数组。 稍后当“my_event_trigger”发生在“obj”上时,将调用 callback_fn。 在回调函数中,我可以通过一个返回空指针的函数访问用户数据,如下所示:

void callback_fn(lv_event_t* e)
{
    lv_event_get_user_data(e); // would return a pointer to my data

    // what I want would be something like
    fp_arr[state]; // where it would call a different function depending on the state of the GUI
}

因此,不幸的是我无法从 void* 更改类型,但我仍然不知道如何以可以访问元素的方式引用它。

【问题讨论】:

  • 我的建议是不要对数组使用 void *,使用实际类型。对于函数指针,创建一个类似typedef int (*function_pointer)(int, int); 的类型别名并像function_pointer fp_arr[4] = { ... }; 一样使用它

标签: arrays c pointers function-pointers


【解决方案1】:

忘记使用return ((int(*)(int, int))ptr)(4, 2);之类的东西吧,那是对每个人时间和理智的巨大浪费。始终使用typedef

  • 这是一个函数void func (void)
  • 这是函数typedef void func_t (void); 的类型定义
  • 这是指向函数类型func_t* f 的函数指针。
  • 这是一个函数指针数组:func_t* f [n]

因此:

void some_func (size_t n, func_t* f[n]);

(可选择使用 func_t* const array[3],因为您可能不想在运行时重新分配它们。)

完整示例:

#include <stdio.h>

typedef void func_t (void);

void blip (void) {puts(__func__);}
void blop (void) {puts(__func__);}
void blup (void) {puts(__func__);}

void some_func (size_t n, func_t* const f[n])
{
  for(size_t i=0; i<n; i++)
  {
    f[i]();
  }
}

int main (void)
{
  func_t* const array[3] = { blip, blop, blup };
  some_func(3, array);
}

【讨论】:

    【解决方案2】:

    在您的示例中,强制转换中缺少 *ptr 是指向函数指针数组的指针:

    int function(void *ptr)
    {
        return ((int(**)(int, int))ptr)[2](4, 2);
    }
    
    int main()
    {
        int (*fp_arr[4])(int, int) = { add, sub, mult, divide };
        
        printf("%d
    ", function(fp_arr));
        
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-25
      • 2013-06-25
      • 2013-06-05
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多