gpt4 book ai didi

c - 函数指针数组: void** cast

转载 作者:行者123 更新时间:2023-11-30 20:10:22 24 4
gpt4 key购买 nike

我对 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)

我的问题:

  1. (void**) array_apf 真的是 void* array_apv 吗?那么,“函数指针数组”到“指向 void 指针的 void 指针”的转换等于“指向 void 指针数组的 void 指针”吗?既然它有效,看起来就是如此。但我真的不太明白。

  2. 当尝试将其(或部分)更改为 C++ 时,使用模板而不是强制转换为 (void*) 是否是更好的方法?

这是我在这里的第一篇文章。我希望,我可以解释我的问题。如果有什么需要澄清的,请告诉我。

谨致问候并提前致谢

最佳答案

C 代码实际上已损坏。虽然指向任何对象的任何指针都可以转换指向void的指针,但对于指向函数的指针来说却并非如此嗯>。此外,不能保证指向函数的指针可以重新解释为 C 中的指向 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 使用一个仿函数 vector ;因此不需要进行强制转换。

关于c - 函数指针数组: void** cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46236427/

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