C++中的转换无效

invalid conversion in C++

本文关键字:无效 转换 C++      更新时间:2023-10-16

上下文:

我有一段代码,当编译为 C 时可以编译和运行良好,我正在尝试将其移植到 C++ 以便能够在未来的C++程序中使用它。

我在我的程序中使用此结构数据类型。

typedef struct MessageDigest{
int32_t digestLen;
void* ctx;
int (*Init)(void* c);
int (*update)(void* c, const void* data, size_t len);
int (*Final)(uint8_t* md, void* c);
}MessageDigest;

在我的主函数中,我正在影响结构的标识符:

MessageDigest* newMD;
/*Other code*/
newMd->Init=&SHA1_Init; //The problem is here

我收到此错误:

invalid conversion from ‘int (*)(SHA_CTX*) {aka int (*)
(SHAstate_st*)}’ to ‘int (*)(void*)’ [-fpermissive]

我尝试过static_cast<>但它不起作用

错误很明显。您声明

int  SHA1_Init(SHAstate_st*);

由于它的参数被声明为SHAstate_st*,它是否与期望参数为void *的函数指针声明不兼容。

你在这里有两种方法。短的就是用reinterpret_cast。正如我们所知,对于任何当前的编译器,指向 void 或 struct 的指针只是一个地址,它应该可以工作,但恕我直言,它通过严格阅读标准来调用未定义的行为:

newMd->Init=reinterpret_cast<int (*)(void *)(&SHA1_Init); // should work but not really standard compliant

正确的是包装SHA1_Init.

int SHA1_Init_void(void *p) {
return SHA1_Init(static_cast<SHAstate_st *>(p));
}

然后,您可以相应地使用它:

newMd->Init = &SHA1_init_void;

但无论如何,你以错误的方式对待它:你本质上是试图用C++编译 C 代码,这通常会导致许多像这样的小错误。它们确实是不同的语言,并且在极端情况下具有特殊的语义。它通常会导致糟糕的代码没有使用C++语言的所有功能,主要是编译时的类型安全保证。

通常,在 C 结构中具有指向获取void *参数的函数的指针通常可以通过 C++ 中的方法重写来更好地表达。它肯定会涉及更多的初始工作,但恕我直言,您应该考虑以现代C++重写更高级别的代码(使用类、构造函数、方法和派生、可选模板)并调用较低级别的 C 函数。您将获得更多可维护的代码,并在将来有所收获。在一个项目中混合 C 和 C++ 翻译单元是完全可以的,您只需将与 C 相关的包含文件包含在C++源文件中的extern "C" { ... }块中即可。常见的用法是将其直接放在受#ifdef __cplusplus保护的.h文件中,并在另一个 SO 问题中演示:结合 C++ 和 C - #ifdef __cplusplus 如何工作?