【问题标题】:Calling C++ functions from C file从 C 文件调用 C++ 函数
【发布时间】:2012-09-27 06:50:18
【问题描述】:

我对 C 和 C++ 很陌生。但是我有一些 C++ 函数需要从 C 中调用它们。我举了一个例子来说明我需要做什么


main.c

#include "example.h"      
#include <stdio.h>

int main(){   
    helloWorld();
    return 0;
}

example.h

 #ifndef HEADER_FILE
 #define HEADER_FILE

 #ifdef __cplusplus
     extern "C" {
 #endif
         void helloWorld();
 #ifdef __cplusplus
     }
 #endif

 #endif

example.cpp

#include <iostream.h>

void helloWorld(){
    printf("hello from CPP");
} 

它只是不起作用。我仍然在我的main.c 中收到对_helloWorld 的未定义引用的错误。问题出在哪里?

【问题讨论】:

  • 标准 C++ 标头 &lt;iostream&gt; 没有 .h。你的编译器可能有&lt;iostream.h&gt; 作为扩展名,但它的内容是不可预测的。 printf 例如通常来自 &lt;cstdio&gt;
  • 当你不控制C++库时:stackoverflow.com/questions/2744181/…

标签: c++ c merge call


【解决方案1】:

简答:

example.cpp 应包含example.h

更长的答案:

当您在 C++ 中声明一个函数时,它具有 C++ 链接和调用约定。 (实际上,最重要的特性是 name mangling - C++ 编译器更改符号名称的过程,以便您可以拥有具有相同名称但参数类型不同的函数。)extern "C"(出现在你的头文件)是你的方式 - 它指定这是一个 C 函数,可从 C 代码调用,例如。没有损坏。

你的头文件中有extern "C",这是一个好的开始,但是你的C++文件没有包含它并且声明中没有extern "C",所以它不知道将它编译为C功能。

【讨论】:

  • @MSalters - 在这种情况下需要它(或者:这是我推荐的单行修复),这就是链接失败的原因,我正在输入解释。
  • 缺少extern "C"确实是正确的答案,但在法律上也可能出现在.cpp中
  • @MSalters - 这是真的,我知道,但我想要一个简洁的建议,然后是一个详尽的解释......这样他们可以在需要时快速回答,但是还请继续阅读以了解如何做到这一点。
  • @asveikau +1,但这部分的措辞可以更好:…它不知道将其编译为 C 函数(我从你的其余部分知道回答你知道它与命名有关,而不是编译)。
【解决方案2】:

extern "C" 告诉 C++ 声明的函数必须使用 C ABI(应用程序二进制接口),因此,无论语言是 C 还是 C++,您的 void HelloWorld() 总是在外部看到它是 C。

但是你在 cpp 文件中实现它就像它是一个 C++ 文件,C 不知道。

您必须使HelloWorld 的原型对C 和C++ 都保持一致,因此cpp 文件应将其声明为extern "C" void Helloworld() { /*your code here*/ },或者简单地说,来自example.cpp 的#include "example.h",这样,在实现它之前,编译器已经知道它必须遵循 C 约定。

【讨论】:

  • 你是绝对正确的。当我编写相同的程序但将我的 main 编写为“main.cpp”并将在 helloWorld() 之前添加 extern“c”或将“example.h”添加到它时,它可以工作。但是当我在“main.c”文件中添加“example.h”或extern“C”时,它仍然不起作用。
  • @user1702375 - 你不希望 "extern "C" 出现在 .c 文件中。这就是人们在标题中将 #ifdef __cplusplus 放在它周围的原因。
  • 对,也许我只是用错误的语言解释了。我的意思是,当我将 main 作为 cpp 代码“main.cpp”时,此规则有效。但是,当我将 main 作为 c 代码“main.c”时,它仍然无法正常工作。虽然我也在“example.cpp”中添加了example.h。
猜你喜欢
  • 2017-04-02
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多