[英]Why can't I link a mixed C/C++ static library that has a C interface using gcc?
我有一个混合的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?
解决问题的最简单方法是使用g++
进行链接; 这将获得正确的库。
问题是C ++有许多要求,C没有,并且在调用main()
之前做了更多的工作,以确保事情被正确初始化。
如果您坚持使用C编译器进行链接,那么至少您必须使用link命令包含C ++支持库。
您的C ++库在内部仍然是一个C ++库,这意味着它包含来自C ++标准库的各种内务处理函数的外部引用。 为了解决这些链接,您必须链接C ++标准库的最终可执行文件。 gcc
不会自动为你做这件事。 要么明确地将C ++标准库提供给gcc
,要么使用g++
编译器。
归档文件仍然只是一堆目标文件(.o),因此在将它们链接到可执行文件或共享库时,仍然需要与g++
链接以将符号解析为C ++运行时(就像您在错误消息中看到的那样) )。
为了使C函数具有C-linkage,它应该足以将它们包装在extern "C"
块中。 事情可能会变得更加复杂,例如Windows,它的无数链接宏(STDCALL,WINAPI等)扩展到其他东西(某些特定于编译器),如__stdcall,__ declspec(导出)等。
您看到的错误似乎是由于缺少与标准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 ++运行时presuma。 当你链接C文件时,你的chimaera仍然是一个C ++程序,即使它是main()和你库外的其他东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.