函数指针数组:void** cast
function pointer array: void** cast
我对 C 和 C++ 比较陌生。我有任务(更多的是练习)将给定的 c 模块更改为 c++。为此,我必须先了解c文件。
我有两个具体问题,但我想简要概述一下函数的各个部分。我尝试使用通用标识符。
c代码摘录:
有一个 Broker 提供注册回调函数。 Broker 在各自的数组中保存不同类型的回调。
首先,他们声明了几个函数指针来指定回调:
typedef bool (*ReadRequestCallback_tpf) (param1 a, param2 b, param3 c);
typedef bool (*ReadResponseCallback_tpf) (param4 a, param5 b);
typedef bool (*WriteRequestCallback_tpf) (param6 a, param7 b, param8 c);
...
然后,他们为每种类型制作了数组来保存注册的回调:
ReadRequestCallback_tpf ReadRequest_apf [MaxReadRequest];
ReadResponseCallback_tpf ReadResponse_apf [MaxReadResponse];
WriteRequestCallback_tpf WriteRequest_apf [MaxWriteRequest];
提供了注册新回调函数:
void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){
AddCallback_v((void**)ReadRequest_apf, (void*) callback_pf);
}
void RegisterReadResponseCallback_v (ReadResponseCallback_tpf callback_pf){
AddCallback_v((void**)ReadResponse_apf, (void*) callback_pf);
}
void RegisterWriteRequestCallback_v (WriteRequestCallback_tpf callback_pf){
AddCallback_v((void**)WriteRequest_apf, (void*) callback_pf);
}
AddCallback_v
的签名是这样的:
void AddCallback_v (void* Array_apv[], void* function_pf)
我的问题:
是(void**) array_apf
真的void* array_apv
吗?
所以 'array of function pointers' 到 'void-pointer to void-pointer' 的转换等于 'void-pointer to an array of void-pointer'?
因为它有效,所以看起来是这样。但我真的不明白。
当尝试将它(或部分)更改为 c++ 时,使用模板而不是强制转换为 (void*) 是否更好?
这是我在这里的第一个条目。我希望,我可以解释我的问题。如果有什么需要澄清的,请告诉我。
谨致问候并提前致谢
当数组传递给函数时,它会自动转换为指向第一个元素的指针。所以在函数声明中,TYPE array[]
等同于 TYPE *array
。因此,void *array[]
等价于 void **array
.
模板的目的之一是避免必须将 void *
类型用于泛型函数,因为编译器无法确保您将其转换回使用指针时的原始类型。所以是的,模板通常是比采用 void*
参数的函数更好的解决方案。
C 代码实际上已损坏。 指向任何对象的任何指针都可以转换为指向void的指针,但事实并非如此指向函数的指针。此外,不能保证指向函数的指针可以 reinterpreted 作为 C 中的 pointer-to-void。这意味着函数
void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){
AddCallback_v((void**)ReadRequest_apf, (void*) callback_pf);
}
在很多方面都被破坏了,包括它破坏了严格的别名。错得让人心疼
这样做的目的显然是有一个名为 AddCallback_v
的通用函数获取指向回调数组的指针,以及一个新的回调函数,但是 C 不保证它会像那样工作!
在 C 中,编写此代码的正确方法是让 Readrequest_apf
等成为通用 函数指针 的数组;在调用它们之前将被转换回 ReadRequestCallback_tpf
等人,即
typedef bool (*GenericCallback_tpf)();
GenericCallback_tpf ReadRequest_apf[MaxReadRequest];
void AddCallback_v(GenericCallback_tpf callback_array[]);
void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){
AddCallback_v(ReadRequest_apf, (GenericCallback_tpf)callback_pf);
}
调用时:
((ReadRequestCallback_tpf)ReadRequest_apf[i])(param1, param2, param3);
在 C++ 中,您将为每个 *_apf
使用一个 函子向量 ;因此不需要强制转换。
我对 C 和 C++ 比较陌生。我有任务(更多的是练习)将给定的 c 模块更改为 c++。为此,我必须先了解c文件。
我有两个具体问题,但我想简要概述一下函数的各个部分。我尝试使用通用标识符。
c代码摘录:
有一个 Broker 提供注册回调函数。 Broker 在各自的数组中保存不同类型的回调。
首先,他们声明了几个函数指针来指定回调:
typedef bool (*ReadRequestCallback_tpf) (param1 a, param2 b, param3 c);
typedef bool (*ReadResponseCallback_tpf) (param4 a, param5 b);
typedef bool (*WriteRequestCallback_tpf) (param6 a, param7 b, param8 c);
...
然后,他们为每种类型制作了数组来保存注册的回调:
ReadRequestCallback_tpf ReadRequest_apf [MaxReadRequest];
ReadResponseCallback_tpf ReadResponse_apf [MaxReadResponse];
WriteRequestCallback_tpf WriteRequest_apf [MaxWriteRequest];
提供了注册新回调函数:
void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){
AddCallback_v((void**)ReadRequest_apf, (void*) callback_pf);
}
void RegisterReadResponseCallback_v (ReadResponseCallback_tpf callback_pf){
AddCallback_v((void**)ReadResponse_apf, (void*) callback_pf);
}
void RegisterWriteRequestCallback_v (WriteRequestCallback_tpf callback_pf){
AddCallback_v((void**)WriteRequest_apf, (void*) callback_pf);
}
AddCallback_v
的签名是这样的:
void AddCallback_v (void* Array_apv[], void* function_pf)
我的问题:
是
(void**) array_apf
真的void* array_apv
吗? 所以 'array of function pointers' 到 'void-pointer to void-pointer' 的转换等于 'void-pointer to an array of void-pointer'? 因为它有效,所以看起来是这样。但我真的不明白。当尝试将它(或部分)更改为 c++ 时,使用模板而不是强制转换为 (void*) 是否更好?
这是我在这里的第一个条目。我希望,我可以解释我的问题。如果有什么需要澄清的,请告诉我。
谨致问候并提前致谢
当数组传递给函数时,它会自动转换为指向第一个元素的指针。所以在函数声明中,
TYPE array[]
等同于TYPE *array
。因此,void *array[]
等价于void **array
.模板的目的之一是避免必须将
void *
类型用于泛型函数,因为编译器无法确保您将其转换回使用指针时的原始类型。所以是的,模板通常是比采用void*
参数的函数更好的解决方案。
C 代码实际上已损坏。 指向任何对象的任何指针都可以转换为指向void的指针,但事实并非如此指向函数的指针。此外,不能保证指向函数的指针可以 reinterpreted 作为 C 中的 pointer-to-void。这意味着函数
void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){
AddCallback_v((void**)ReadRequest_apf, (void*) callback_pf);
}
在很多方面都被破坏了,包括它破坏了严格的别名。错得让人心疼
这样做的目的显然是有一个名为 AddCallback_v
的通用函数获取指向回调数组的指针,以及一个新的回调函数,但是 C 不保证它会像那样工作!
在 C 中,编写此代码的正确方法是让 Readrequest_apf
等成为通用 函数指针 的数组;在调用它们之前将被转换回 ReadRequestCallback_tpf
等人,即
typedef bool (*GenericCallback_tpf)();
GenericCallback_tpf ReadRequest_apf[MaxReadRequest];
void AddCallback_v(GenericCallback_tpf callback_array[]);
void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){
AddCallback_v(ReadRequest_apf, (GenericCallback_tpf)callback_pf);
}
调用时:
((ReadRequestCallback_tpf)ReadRequest_apf[i])(param1, param2, param3);
在 C++ 中,您将为每个 *_apf
使用一个 函子向量 ;因此不需要强制转换。