【问题标题】:invalid conversion in C++ [closed]C ++中的无效转换[关闭]
【发布时间】:2017-05-11 12:48:07
【问题描述】:

上下文:

我有一段代码在编译为 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<>,但它不起作用

【问题讨论】:

  • 显示SHA1_Init的定义
  • 该消息是不言自明的。 int (*)(SHA_CTX*)int (*)(void*) 不同,您不能将一个分配给另一个。
  • 得问...为什么在 C++ 中使用这样的函数指针?它与某些遗留的 C 库有关吗?
  • 从语言实现的角度来看,在 CPP 中使用它是非常好的,这就是我所说的。它既不被认为是“现代的”也不被认为是类型安全的,这写在另一张纸上。 “auto”关键字也是现代的,它是类型安全的,但我仍然认为它很糟糕,因为它通过将“所有类型推导给编译器”并给出一个 sh** 来降低现代 cpp 编码器的意识是什么有效地完成。正确使用 void* 至少需要开发人员知道他在做什么。但这很哲学:D @hyde

标签: c++ type-conversion


【解决方案1】:

错误是明确的问题。你声明

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 问题中进行了演示:Combining C++ and C - how does #ifdef __cplusplus work?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    相关资源
    最近更新 更多