如何将c++文件链接到C程序
How can I link C++ files to a C program?
我目前正在尝试将一个大的c++程序链接到C"包装器",以允许与另一种语言的程序集成,其编译器理解C但不理解c++ (Haskell GHC,准确地说)。但是我尝试这样做,无论是用GHC还是GCC,都会遇到奇怪的问题。
为了简洁地模拟这种情况,假设我在C中有一个主程序文件:cmain.c
#include "header.h"
#include <stdio.h>
int main () {
printf("%dn", cppfun(12));
return 0;
}
和.cpp文件中定义的辅助函数:
cppmodule.cpp
#include "header.h"
#include "further.h"
class foobar {
public:
int getfive () {return 5;}
};
extern "C" {
int cppfun(int foo) {
foobar fb;
return fb.getfive();
}
}
这段代码可以很好地编译。但是,如果cppmodule.cpp引用另一个.cpp文件,如下所示:
cppmodule.cpp mk II
#include "header.h"
#include "further.h"
class foobar {
public:
int getfive () {return 5;}
};
extern "C" {
int cppfun(int foo) {
foobar fb;
return fb.getfive() + morecpp();
}
}
,其中新的。cpp文件类似;
morecpp.cpp
#include "further.h"
class moreobjects {
public:
int getsix() {return 6;}
};
#ifdef __cplusplus
extern "C" {
#endif
int morecpp() {
moreobjects mo;
return mo.getsix();
}
#ifdef __cplusplus
}
#endif
当我试图用像"gcc cmain"这样的命令编译时,我突然得到一个错误。o cppmodule。o morecpp.o";用g++编译可以工作,但是,正如我提到的,这种解决方案不符合我的目的。
我得到的错误试图编译这个例子是
max@SoutheastCorner:~/Projectsync/maketest$ gcc cmain.o cppmodule.o morecpp.o
cppmodule.o:(.eh_frame+0x4b): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status
在我的实际项目代码中进行同样的尝试,另外给出了完整屏幕的
形式的错误hopnode.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeI4nodeIPcS3_EEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeI4nodeIPcS3_EEE8allocateEmPKv]+0x4d): undefined reference to `operator new(unsigned long)'
/tmp/ccaoEEFM.o: In function `__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<char* const, node<char*, char*> > > >::allocate(unsigned long, void const*)':
hopnode.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKPc4nodeIS3_S3_EEEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKPc4nodeIS3_S3_EEEE8allocateEmPKv]+0x2c): undefined reference to `std::__throw_bad_alloc()'
hopnode.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKPc4nodeIS3_S3_EEEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKPc4nodeIS3_S3_EEEE8allocateEmPKv]+0x46): undefined reference to `operator new(unsigned long)'
问题出在链接阶段。您的程序缺少c++标准库中的符号。要解决这个问题,你必须要么链接到c++驱动程序,要么明确地链接到c++标准库。
使用g++链接是最简单的解决方案,但您也可以尝试将-lstdc++
添加为库标志。
请记住,与此相关的陷阱仍然很多。c++ ABI并不简单,而且不一定在不同的编译器(clang/g++/等)甚至不同版本的GCC之间保持一致。如果您的Haskell程序动态链接到使用不同的c++ ABI编译的其他c++代码,这可能会出现问题。
还要注意,还必须捕获C/c++边界的所有异常。Haskell期望一个直接的C ABI,不能处理通过C/c++边界泄漏的c++异常。
如果您想在C代码中使用c++代码,请在您的C程序使用的所有c++代码周围使用extern "C++"
。然后你可以把它编译成一个C程序,Haskell甚至不会知道它是用一些c++代码在幕后实现的。
编辑:我从来没有尝试过这个方向(通常你在c++项目中使用C代码),但基本上这就是它应该如何工作。
如果它不能正常工作,试着用g++像编译任何普通的c++程序一样编译c++程序,然后编写一个使用它的C程序。
我会尝试将extern "C"添加到将在C中调用的c++函数中。c++编译器必须知道该函数将由C编译器使用extern "C"结构调用。
//在你的c++代码中
//使用extern " c "声明function(char, int)为c函数:
…
//在c++模块中实现function(char,int):Void函数(char c, int i){...}
- 基于boost的程序的静态链接——zlib问题
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 将gsl c++程序与"英特尔MKL"链接
- 将 glade 文件与程序 g++ 链接
- Qt creator 4.11,在应用程序输出面板中创建一个链接
- 在树莓派上用libtorch构建程序时的链接问题
- 如何将SQLite c文件(合并)与cpp应用程序链接?
- 共享对象与提升program_options静态链接;应用程序链接共享
- 在Visual Studio 2013中使用Qt和OpenCV创建应用程序链接问题
- C++:运行时将共享对象与主机应用程序链接,符号表问题
- OpenGL 着色器不与着色器程序链接
- 将 DLL 与应用程序链接时出现未知错误
- 创建要与C++程序链接的静态 CUDA 库
- 如何将C++/CLI程序编译到.lib中,并将其与纯非托管C++程序链接
- 是否有一种方法将我的GCL Lisp文件与Windows上的单独c++程序链接
- 无法将xerces2_7.dll与64位应用程序链接
- 你能从一个C应用程序链接一个c++库吗?
- 通过 FFI 块从 Haskell 调用共享库,而从 C 程序链接时则不会
- 您是否可以拥有一个具有管理员权限的DLL,该DLL从仅具有用户级权限的客户端应用程序链接
- GLSL - 程序链接错误:插槽 0 在布局位置请求中不可用