gpt4 book ai didi

c - 函数指针转换

转载 作者:太空宇宙 更新时间:2023-11-03 23:20:09 24 4
gpt4 key购买 nike

大家好,我目前面临一个非常烦人的问题:

我正在编写一个通过使用函数指针工作的回调管理器系统,现在考虑到到目前为止我已经被分配给一些其他非空函数指针的空函数指针,我已经意识到它不是实际上在 C 中是允许的。

目前我正在考虑强制转换 void 指针,以便与我为每个回调设置的原型(prototype)函数相匹配,但我无法理解如何实现强制转换

它可行还是我应该采用其他解决方案?

目前这些是我的回调容器及其类型定义:

typedef void modbus_read_t(unsigned int uid, unsigned int address, unsigned int count, char* response);
typedef void modbus_write_t(unsigned int uid, unsigned int address, unsigned int *data, char* response);

typedef void system_read_t(unsigned int uid, unsigned int var_number, unsigned int count, char* response);
typedef void system_write_t(unsigned int uid, unsigned int var_number, struttura_system *storage, char* response );

void (*M_callbacks_r[3]) (unsigned int uid, unsigned int address, unsigned int count, char* response);
void (*M_callbacks_w[2]) (unsigned int uid, unsigned int address, unsigned int *data, char* response);
void (*P_callbacks_r[2]) (unsigned int uid, unsigned int var_number, unsigned int count, char* response);
void (*P_callbacks_w[2]) (unsigned int uid, unsigned int var_number, struttura_system *storage, char* response );

这是注册回调函数的原型(prototype):

void registerCallback(int systemType,int operationType, void (callback)(void*));

必须做的是将 void (callback)(void*) 转换为上述类型定义之一。

最佳答案

嗯,类型转换应该工作。 C 标准允许在函数指针类型之间进行转换,您唯一不应该做的就是通过具有错误原型(prototype)的函数指针调用函数,即在调用之前转换回正确的原型(prototype),以避免未定义的行为。

为了便于阅读,让我们先稍微简化一下数组:

modbus_read_t*  M_callbacks_r[2];
modbus_write_t* M_callbacks_w[2];
system_read_t* P_callbacks_r[2];
system_write_t* P_callbacks_w[2];

我不知道你为什么typedef输入函数类型而不是函数指针类型,但我会接受它。

现在registerCallback可以实现如下:

void registerCallback(int systemType,int operationType, void (*callback)()) {
// .. determine array by system type and operation type
M_callbacks_r[0] = (modbus_read_t*)callback;
}

我从 callback 原型(prototype)中删除参数的原因是,在标准 C 中,空参数列表不传达有关预期参数的信息(与 C++ 相反,它明确表示“无参数” ”)。这样就可以在不需要强制转换的情况下注册回调。


正如您在评论中提到的,您正在使用 -Wstrict-prototypes -Werror 进行构建。所以一个空的参数列表对你不起作用。因此,您只能像这样定义 registerCallback:

void registerCallback(int systemType,int operationType, void (*callback)(void))

注意参数列表中显式的void。您需要在将回调传递给 registerCallback 时对其进行强制转换,并将其强制转换回函数本身。

registerCallback(type, op, (void(*)(void))func_cb);

旁注:_t 后缀在 POSIX 系统上保留。为了便携,最好不要用它来命名你的类型。

关于c - 函数指针转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41974699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com