我有一个混合的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
test2是我的测试工具。
当我使用g ++时,不会发生此问题。但是,我要将这个库连接到用gcc编译的C项目中。我该如何解决这个问题?它的原因是什么?
修改
即使我没有使用标准的C ++库,显然还需要一些像operator new / delete等的东西,内部也有异常。
我将这个东西与Xen管理程序相关联,所以我不确定我有什么选择,但要完全改写这个东西,或者尝试用G ++编译Xen?
答案 0 :(得分:9)
解决问题的最简单方法是与g++
链接;这样就可以得到正确的库。
问题在于C ++有许多要求,但是在调用main()
之前做了更多工作以确保事情被正确初始化。
如果你坚持使用C编译器进行链接,至少你必须使用你的链接命令包含C ++支持库。
答案 1 :(得分:2)
您的C ++库在内部仍然是一个C ++库,这意味着它包含来自C ++标准库的各种内务处理函数的外部引用。为了解决这些链接,您必须链接C ++标准库的最终可执行文件。 gcc
不会自动为您执行此操作。要么明确地将C ++标准库提供给gcc
,要么使用g++
编译器。
答案 2 :(得分:1)
归档文件仍然只是一堆目标文件(.o),因此在将它们链接到可执行文件或共享库时,仍然需要与g++
链接以将符号解析为C ++运行时(如一旦你看到错误信息)。
要使C函数具有C-linkage,它应该足以将它们包装在extern "C"
块中。事情可能会变得更复杂,例如Windows,它的无数链接宏(STDCALL,WINAPI等)扩展到其他东西(某些特定于编译器),如__stdcall,__ declspec(export)等。
答案 3 :(得分:1)
您看到的错误似乎是由于缺少与标准C ++库的链接而出现的,该库具有operator new,operator delete等符号定义。尝试链接stdc++
说gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 -lstdc++
。 Jonathan Leffler建议使用g++
代替gcc
答案 4 :(得分:0)
在C ++中编写可以在没有任何C ++要求的额外内容的情况下使用的东西非常难。甚至可能依赖于编译器。您的库需要C ++运行时,并且在程序中调用main()之前需要特殊支持来初始化C ++运行时presuma。当你在C文件中链接时,你的chimaera仍然是一个C ++程序,即使它是main()和你库外的其他东西。