我想从下面用原型定义的 OpenSSL 库中调用这个函数:
X509 *d2i_X509(X509 **px, const unsigned char **in, int len);
第二个参数in
定义为a const unsigned char **
,因为:
- d2i_X509 不会修改指向的缓冲区中的数据
*in
*in
将从缓冲区解析的数据量增加。
现在这个原型是一个问题,因为据我所知,该函数不能以以下方式调用,据我所知,API 是调用它的正常方式(删除了错误管理代码以使事情变得更简单):
unsigned char buffer[2048];
unsigned char * end = buffer;
unsigned char * p = buffer;
end += read(fd, p, 2048);
certlen1 = parseint(&p);
X509 * cert1 = d2i_x509(NULL, &p, certlen1);
certlen2 = parseint(&p);
X509 * cert2 = d2i_x509(NULL, &p, certlen2);
如果我尝试编译上面的代码,它会说:
error: invalid conversion from 'unsigned char**' to 'const unsigned char**'
我理解消息的基本原理(例如在此处解释),但在这种特殊情况下,此基本原理并不适用,因为函数在其文档中声明它只会增加 的值*in
,而不会为其分配不相关的指针。
我无法将 p 的类型更改为,const unsigned char *
因为上面的代码实际上是简化的,指针隐藏在一些执行读取和写入的抽象 IO 对象后面。前一个 IO 对象的好处是保持对称读写代码在一起,可以在我的 IO 对象中使用两个单独的指针进行读写,但这样做的总体好处非常小(如果不是负面的话)并添加很多语法噪音。由一些外部无关的 API 调用强制在 IO 对象中进行那种深度的内部变化,看起来真的很牵强。
一个解决方案可能是执行强制转换,甚至根本不使用返回的指针值(因为我有 size 参数),但感觉也不对。在这种情况下,似乎 d2i_X509 的原型没有包含足够的信息,或者编译器的 const 检查规则过于严格。
应该如何从 C++ 调用这样的 API?现在我只会使用演员表,因为我觉得它是较小的邪恶,但有没有更好的方法?