【问题标题】:Why do hiredis functions use void* instead of redisReply*?为什么hiredis函数使用void*而不是redisReply*?
【发布时间】:2019-06-21 13:25:03
【问题描述】:

我是hiredis 新手,使用v0.13。我注意到hiredis.h 中处理redisReply* 对象的API 函数都使用void*。例如,

void *redisCommand(redisContext *c, const char *format, ...);

返回一个redisReply* 对象(或NULL);

int redisGetReply(redisContext *c, void **reply);

通过reply输出一个redisReply*对象;

void freeReplyObject(void *reply);

根据代码注释,是“默认情况下释放hiredis返回的回复对象的函数”。

我在这里遗漏了什么——为什么这些函数使用void* 而不是redisReply*

【问题讨论】:

    标签: c hiredis


    【解决方案1】:

    我注意到hiredis.h 中处理redisReply* 对象的API 函数都使用void*

    我能看到解释您的描述的唯一明智的方法是,您已经分析了实现以发现 在内部,它使用指向名为 redisReply 的类型的指针,但接口处理此类指针通过类型 void * 代替。

    这将是一种强制该 API 的客户端将回复对象指针作为opaque values 处理的机制。客户端(可能)没有redisReply 的定义,甚至没有它的名称,并且在回复指针和该类型之间没有声明的关联,因此 API 明确避免为客户端提供创建此类对象的方法或解释或修改它们的值,而不是通过 API 自己的函数。他们所能做的就是从 API 接收那些不透明的指针并将它们传回。

    不过,我还要说,这种处理不透明指针的特殊方法很糟糕。可以在不放弃不透明度的情况下提供更好的类型安全性,如上面链接问题的答案所示。

    【讨论】:

      【解决方案2】:

      通用函数通常以这种方式编写,因为您可以将任何指向 void * 和 void * 的指针转换为相同的指针(对于 char 指针类型也是如此)而没有风险和可移植性。您也不会收到任何编译器警告。

      【讨论】:

      • OP 示例中的函数(表面上)不是通用的。也就是说,我还没有看过实现……可以想象这是一个不透明的指针,而实际的内部对象类型是不同的,恰好与redisReply* 的布局兼容。但即使在这种情况下,在公共界面中使用 void* 而不是 redisReply* 也没有任何意义。
      • 我假设OP的信息是正确和完整的,并且对应API文档。他们说“[那个函数]返回一个redisReply*”所以这是我的工作假设。诚然,如果我们还假设该 API 的开发人员知道他们在做什么,那么这些假设似乎不太可能是正确的。
      • 不,此函数仅返回此类型 void * 。 return 语句中的内容无关紧要
      • 老实说,hiredis 的文档不是很精确——我希望有使用它经验的人能给点建议。无论如何,这里有一个来自hiredis.h 的具体声明:github.com/redis/hiredis/blob/master/hiredis.h#L100-L101/* This is the reply object returned by redisCommand() */ typedef struct redisReply { ... 再往下是函数声明github.com/redis/hiredis/blob/master/hiredis.h#L285 ` void *redisCommand(redisContext *c, const char *format, ...); `
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      相关资源
      最近更新 更多