C 为什么hiredis函数使用void*而不是redisReply*?

C 为什么hiredis函数使用void*而不是redisReply*?,c,hiredis,C,Hiredis,我不熟悉hiredis,使用v0.13。我注意到hiredis.h中处理redisReply*对象的API函数都使用void*。比如说, void*redisCommand(redisContext*c,const char*格式,…); 返回一个redisReply*对象(或NULL) int redisGetReply(redisContext*c,void**reply); 通过reply输出一个redisReply*对象 void freeplyobject(void*reply);

我不熟悉hiredis,使用v0.13。我注意到
hiredis.h
中处理
redisReply*
对象的API函数都使用
void*
。比如说,

void*redisCommand(redisContext*c,const char*格式,…);
返回一个
redisReply*
对象(或
NULL

int redisGetReply(redisContext*c,void**reply);
通过
reply
输出一个
redisReply*
对象

void freeplyobject(void*reply);
根据代码注释,它是一个“释放hiredis默认返回的回复对象的函数”


为什么这些函数使用
void*
而不是
redisReply*

通用函数通常是这样编写的,因为您可以将指向void*和void*的任何指针强制转换为同一指针(关于char指针类型的指针相同),而不存在风险和可移植性。您也不会得到任何编译器警告

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

我能看到的解释您的描述的唯一合理方法是,您分析了实现,发现在内部,它使用指向名为
redisrepl
的类型的指针,但接口通过type
void*
处理此类指针

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


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

OP示例中的函数(表面上)不是通用的。也就是说,我还没有研究实现……可以想象,这是一个不透明的指针,实际的内部对象类型是与
redisReply*
布局兼容的不同类型。但即使在这种情况下,在公共界面中使用
void*
而不是
redisReply*
也没有真正意义。我假设OP的信息是正确和完整的,并且与API文档相对应。他们说“[该函数]返回一个
redisReply*
”,这就是我的工作假设。诚然,如果我们还假设API的开发人员知道他们在做什么,那么这些假设似乎不太可能都是正确的。不,这个函数不返回这种类型,只返回
void*
。返回声明中的内容并不重要说实话,hiredis的文档不是很精确——我希望有使用经验的人能给出一些建议。无论如何,这里是hiredis.h的一个具体语句:
/*这是redisCommand()返回的reply对象*/typedef struct redisReply{…
下面是函数声明'void*redisCommand(redisContext*c,const char*format,…)`