为什么我无法使用 gcc 链接具有 C 接口的混合 C/C++ 静态库?
Why can't I link a mixed C/C++ static library that has a C interface using gcc?
我有一个C/c++混合库。
在外部,它使用extern C提供了一个C接口。内部有模板和类。用"ar"创建库没有任何问题。文件名为lib -client.a。然而,当使用gcc(不是g++)链接.a
文件时,我得到了很多错误,看起来像这样:
libo-client.a(mysocket.o):(.rodata._ZTV7mStream[vtable for mStream]+0x10): undefined reference to `__cxa_pure_virtual'
...
mysocket.cpp:(.text+0x15ad): undefined reference to `operator new[](unsigned long)'
mysocket.cpp:(.text+0x15c1): undefined reference to `operator delete(void*)'
mysocket.cpp:(.text+0x167a): undefined reference to `__cxa_allocate_exception'
mysocket.cpp:(.text+0x16a6): undefined reference to `__cxa_throw'
...
我的编译/链接行是这样的:
gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2
test2是我的测试工具
当我使用g++时,这个问题不会发生。但是,我将把这个库接口到用gcc编译的C项目中。我该怎么解决这个问题?它的原因是什么?
编辑:虽然我没有使用标准的c++库,但它显然需要一些像operator new/delete之类的东西,并且内部有异常。
我链接这个东西对Xen管理程序,所以我不确定我有什么选择,但完全重写这个东西,或者也许尝试编译Xen与g++代替?
解决问题的最简单方法是与g++
链接;这会得到正确的库。
问题是c++有很多C没有的要求,并且在调用main()
之前做了更多的工作来确保事情被正确初始化。
如果你坚持与C编译器链接,至少你必须在你的链接命令中包含c++支持库
您的c++库在内部仍然是一个c++库,这意味着它包含对来自c++标准库的各种管理函数的外部引用。为了解决这些链接,你必须链接c++标准库的最终可执行文件。gcc
不会自动为您做这件事。要么显式地为gcc
提供c++标准库,要么使用g++
编译器。
归档文件仍然只是一堆目标文件(.o),所以当将它们链接到可执行库或共享库时,您仍然需要链接g++
以将符号解析到c++运行时(就像您在错误消息中看到的那样)。
要使C函数具有C链接,将它们包装在extern "C"
块中就足够了。事情可能会变得更复杂,例如Windows,它有无数的链接宏(STDCALL, WINAPI等),扩展到其他东西(一些编译器特定的),如__stdcall, __declspec(export)等。
您看到的错误似乎是由于缺少与标准c++库的链接而出现的,该库具有operator new, operator delete等的符号定义。试着连接stdc++
和gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 -lstdc++
。更好的选择是由Jonathan Leffler建议使用g++
而不是gcc
用c++编写可以在C中使用的东西,而不需要c++需要的任何额外的东西是非常困难的。甚至可能依赖于编译器。您的库需要c++运行时,并且在程序中调用main()之前初始化c++运行时可能需要特殊的支持。当你链接C文件时,你的chimaera仍然是一个c++程序,即使它是main()和库外的其他所有东西。
- 混合组合和继承的C++问题
- 在混合代码库中将C转换为C++时出现许多包含错误
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- Visual C++GC接口如何启用它以及要包含哪个库
- Windows.h与GLFW.h的接口
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- D3D11-将混合权重和索引传递到顶点着色器
- 提供与TMP和SFINAE的通用接口
- 为重写std::exception的库生成swig接口时出错
- 内联如何影响模块接口中的成员函数
- COM 接口 c# 封送数组数组
- 如何在 SCIP C++ 接口中获取 MILP 约束矩阵中的系数值
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如何绑定 C++ gRPC 客户端的网络接口
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何从实现接口的模板化类实例访问结构
- C++分数混合比较运算符错误
- 带有进度表的 curl 多接口程序
- API 抽象层 - 避免混合使用 API 接口
- 为什么我无法使用 gcc 链接具有 C 接口的混合 C/C++ 静态库?