通用 void internaldeliver(void *ctx, packet *p); 解释一下其中 void *ctx的书写格式来历,这些写作的好处

void *ctx 这种写法在这份代码里其实是一个可以验证的具体模式,不是泛泛而谈。

来历

void * 是 ANSI C (C89) 里引入的"通用指针"类型——可以指向任意对象,且赋值给它或从它赋值给别的指针类型时不需要显式 cast(这点和 C++ 不同,C++ 要求显式转换)。ctx(context 的缩写)是一种命名惯例,专门用在回调函数场景:函数指针本身的签名是固定的,但每个注册者想携带的"私有数据"类型各不相同,于是就用 void * 把这块数据的类型抹掉,等回调真正被调用时再转型回具体类型。

这么写的好处

  1. C 没有泛型/模板,void *ctx 是 C 里模拟"带状态的回调"(类似 C++ 的仿函数/闭包)最标准的手段——同一个 tx 函数指针字段可以配上完全不同类型的关联数据(这里是 internal_bus_t *),而不需要为每种可能的调用者单独定义结构体或函数签名。
  2. 解耦:调用回调的那一层(vswitch 路由核心)完全不需要认识 internal_bus_t 这个类型,只需要把注册时存的 ctx 原样传回去;类型知识留在回调实现者(internal_bus_deliver)这一侧。
  3. 同一套分发机制可以复用:不管挂的是 internal_bus_deliver 还是别的 handler,vswitch 核心的调用代码都不用改。

代价

(值得知道,不是这段代码的问题,是 void *ctx 模式本身的固有权衡):牺牲了编译期类型检查——如果注册时传错了 ctx 的类型,编译器不会报错,只有运行到 (internal_bus_t *)ctx 转型后访问野内存才会暴露问题。所以这类代码通常靠"注册处和使用处的类型必须手动保持一致"的约定来保证正确性

 

posted on 2026-09-28 18:19  ENGINEER-F  阅读(1)  评论(0)    收藏  举报