2016-04-27 93 views
4

在C程序中,我需要获取对位于用C++编写的库中的函数的引用。
下面是代码在c程序中获取指向C++函数库的指针

// Some C includes 
#include <cpplib.h> 
. 
. 
. 
// A C structure attribute pointing to the C++ function 
infoptr.EXT_meshAdapt = &meshAdapt; 

的部分问题是编译器告诉我有一个未定义的引用meshAdapt,而当我做同样的C库是没有问题的。

在这个thread我看到我们可以通过制作一个包装来调用C中的C++函数。但是有没有一种方法可以引用一个C++函数而不需要封装?

+1

您可能可以通过使用C++函数的错位名称来完成它,但它看起来像一个丑陋的黑客。 –

+0

你是什么意思? (我真的不知道C++) – Phantom

+0

如果'meshAdapt'应该可以从'C'调用,那么你应该在头文件中声明它(并在它的lib中实现)为'extern“C”'。唯一的办法,我看到不工作是如果该功能需要重载,在这种情况下,一个'extern“C”'包装是关于你唯一的近乎平凡的选择。 – WhozCraig

回答

7

通常,C++中的编译器会破坏函数的名称。这意味着你写的函数添加两个数字为

int add(int a, int b); 

会被损坏。 (意味着它看起来像@ZVVVZaddDFD)。所以,如果你想从C代码使用这个函数,那么你必须调用@ZVVVZaddDFD而不是add

或者更好的选择是请求编译器避免对您打算在C代码中使用的函数进行修改。

你可以做到这一点: -

extern "C" 
{ 
    int add(int a, int b); 
} 
+0

但是,为此,他需要重新编译他的C++库:D – sjsam

+0

而且我无法修改C++头文件:s – Phantom

1

当编译C++程序,names are mangled。使用extern "C"块可防止编译器破坏其内部的内容。

现在,如果您不想使用“包装”extern "C" @Paul建议您使用重名的名称。

4

正如在其他答案中所述,C++ mangles函数的标识符。这样做是为了允许函数重载,因为不同的重载会得到不同的重名,并且链接器可以识别它们。

不幸的是,标准没有指定名称修改,因此不同的编译器(或不同版本的编译器)可以使用不同的修改方案。

所以唯一可移植的方法是声明函数本身或包装它,如果它可以支持重载如extern "C"要求编译器生成一个unmangled标识符。

所以在这里你可以做(​​在C++代码):

extern "C" { 
    int c_meshAdapt() { 
     return meshAdapt(); 
    } 
} 

,并在C代码:

infoptr.EXT_meshAdapt = &c_meshAdapt; 
0

这是基于你只有一个未定义的引用错误的假设。

从C++源复制你得到未定义的引用的函数。假设它是calsum()。让我们用C++的方式来做。

创建函数的C-指明分数版本

写入新的程序说mymath.cpp只是功能。假设该函数的源代码如下。

extern "C" int calsum(int x,int y) 
/*I have added an extern "C" for the reasons others suggested*/ 
{ 
return x+y; 
} 

编译程序

g++ -c mymath.cpp -o mymath.o 

现在,你应该有一个文件mymath.o

的目标代码创建库

务必:

ar -src libmymath.a mymath.o 

在上面的步骤中,您只需添加创建一个名为libmymath.a的静态库并添加mymath.o即可。如有疑问,请参阅手册页。所有这些名字与合理的名称

替换最后

编译你的C程序,做

gcc your_c_program.c -o your_c_program.elf -L. -lmymath 

就大功告成了。

+0

编译器似乎不喜欢'extern“C”'。它预计'('之前的''C''。然后我有一个错误'meshAdapt未申报:首次在此功能使用'。 – Phantom

+0

您使用'-c'选项与g ++? – sjsam

+0

是的,我用这个选项 – Phantom