是否可以从C源代码调用C ++函数?
请建议。
非常感谢。
答案 0 :(得分:9)
您需要查看extern C
construct。
从链接:
// This is C++ code
// Declare f(int,char,float) using extern "C":
extern "C" void f(int i, char c, float x);
...
// Define f(int,char,float) in some C++ module:
void f(int i, char c, float x)
{
...
}
您还可以使用extern C
构造声明/定义多个函数,如下所示:
使用extern C
extern "C"
{
void func1();
void func2();
}
extern "C"
{
void func1()
{
/// do something
}
void func2()
{
// do something else
}
}
你甚至可以用#include
包装extern "C"
声明:
extern "C"
{
#include "myHeader.h"
}
以上将导致虚构标题myHeader.h
中的所有内容都具有C链接,但可能导致嵌套包含问题 - 基本上,如果您可以自己直接修改标头文件,请不要使用此结构。这是最后的手段。
<强>注意事项强>
正如Jack Kelly(感谢Jack Kelly!)提到的那样,请确保如果您的C ++代码涉及异常,那么它们将在您的函数中处理,并且不允许传播到C。
使用extern "C"
链接定义的函数不能重载,因为C不允许多个具有相同名称的函数。
您的C和C ++代码必须使用类似的编译器进行编译,因为它们需要就类型,调用约定等达成一致。
引用,因为我不能单独执行此操作
感谢评论者。
答案 1 :(得分:3)
最好/最简单的方法是在c接口中包装所需的c ++位,然后从c源文件中调用c接口。
答案 2 :(得分:2)
答案 3 :(得分:2)
我需要做这样的事情,并将我的实验保存到github:http://github.com/jrockway/cplusplus-binding-examples
libexample ++是我们尝试绑定到C的C ++库.libexample是C绑定;你用C ++编译器编译它,但它产生一个带有C(和其他所有)可以调用的demangled名称的库。它还会将std::string
转换为char *
,依此类推。
最后,有一个examplehs是一个Haskell绑定到libexample,而example-perl是一个perl绑定到libexample。这使您可以通过C。
了解如何从其他语言调用C ++如果我要再次这样做,我会为C结构和C ++类使用不同的名称,如FQA建议的那样。
(另外,为了“为什么这样做”,这是因为只有C ++编译器知道如何调用C ++函数。当你定义一个函数foo
时,编译器将它编译成一个函数运行时工具链的其余部分认为类似于foo_4dskjaf3874hdfas
。这意味着只有C ++编译器才能生成调用它的代码,因为只有C ++编译器才知道实际调用了什么函数。当你使用{{1然后C ++编译器没有“破坏”名称,然后没有命名问题。你可以打开库,调用extern "C"
,并获得你期望的功能。
将C ++绑定到其他语言时,并不总是需要通过C语言; Perl会愉快地调用C ++编译器并让它进行demangling,但GHC Haskell不会。因此,当我尝试将C ++库绑定到某个东西时,我总是通过C,因为很容易将其他所有内容绑定到C.对C ++的任何东西都是命中注定。)
答案 4 :(得分:0)
如果你想从C代码调用函数,并且想要#include
原型的头文件,那么C编译器不能看到任何extern "C"
语句。
请参阅其他SO问题,例如this。