C++ 为什么可以';我链接一个混合C/C++;具有使用gcc的C接口的静态库?

C++ 为什么可以';我链接一个混合C/C++;具有使用gcc的C接口的静态库?,c++,c,gcc,g++,C++,C,Gcc,G++,我有一个混合的C/C++库 在外部,它使用extern C提供了一个C接口。在内部,有模板和类。使用“ar”创建库不会带来任何问题。该文件名为libo client.a 但是,当使用gcc(而不是g++)链接.a文件时,我会遇到如下错误: libo-client.a(mysocket.o):(.rodata._ZTV7mStream[vtable for mStream]+0x10): undefined reference to `__cxa_pure_virtual' ... mysocke

我有一个混合的C/C++库

在外部,它使用extern C提供了一个C接口。在内部,有模板和类。使用“ar”创建库不会带来任何问题。该文件名为libo 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 
我的编译/链接行如下所示:

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++库,但它显然需要一些新的操作,如运算符new /DELL等,并且内部也有例外。
我正在将这个东西链接到Xen管理程序,所以我不确定我有什么选择,只能完全重写这个东西,或者尝试用G++编译Xen?

存档文件仍然只是一堆对象文件(.o),所以当将它们链接到可执行文件或共享库时,您仍然需要链接到<代码> G++<代码>,以将符号解析为C++运行时(就像您在错误消息中看到的)。
要使C函数具有C链接,将它们包装在
extern“C”
块中就足够了。在Windows上,事情可能会变得更复杂,因为有无数的链接宏(STDCALL、WINAPI等)可以扩展到其他东西(一些特定于编译器的东西),比如“STDCALL”、“declspec(export)”等等。

解决问题的最简单方法是链接
g++
;这将获得正确的库

问题是C++有很多的要求,C不需要,并且在调用<代码>()//>代码之前做更多的工作,以确保事物被正确初始化。
如果你坚持与C编译器连接,至少你必须将C++支持库包含在链接命令中。

你看到的错误似乎是由于缺少连接到标准C++库的,它具有运算符new的符号定义,操作员删除等。尝试链接
stdc++
gcc$(CFLAGS)$(包括)test2.c libo client.a-o test2-lstdc++
。更好的选择是Jonathan Leffler建议使用<代码> G++< /C> >而不是<代码> GCC

> P>您的C++库仍然是内部C++库,这意味着它包含了来自C++标准库的各种内务功能的外部引用。为了解决这些链接,你必须把你的最终可执行文件链接到C++标准库。代码>gcc不会自动为您执行此操作。要么明确地将C++标准库提供给<代码> GCC < /C>,要么使用<代码> G++< /Cuth>编译器。C++中的C++编写的

< P>编写的东西,不需要任何额外的C++要求,是非常困难的。甚至可能依赖于编译器。库需要C++运行时,并且初始化C++运行时假定需要在程序中对主程序()进行特殊支持。当C文件中,即使是主文件()和库外的其他内容,你的CimaRa仍然是C++程序。

+ 1——包括C项目中的C++库,不仅仅是在它上面扔对象文件。切换到G++也为我固定了,但是有更便携的方法吗?我如何为非Linux系统编写一个MaxFixe:EdWordFalk?比将(部分)C++程序与C++编译器连接起来更便携?不这将是最便于携带的方法。另一种方法是C++编译器调用链接器来获得C++的东西,然后研究如何用C++编译器自动为你自动调用C编译器来调用链接器。如果你想试试的话,请便,但这样做会非常困难,而且可移植性也会大大降低。如果编译器没有命名为“g++”,该怎么办。Gnu不是唯一的编译器。make中是否有${CC++}宏,相当于${CC}?它通常由宏
${CXX}
表示。在C编译器为“代码> GCC < /COD>”的情况下,C++编译器通常是代码> G++< /COD>。在使用不同编译器时,仍然与用于构建C++对象模块的C++编译器联系起来。使它成为动态库也可能有帮助。你调查过了吗?谢谢,克里斯。它实际上是一个动态共享对象。