繁体   English   中英

为什么我不能使用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”创建库没有任何问题。 该文件名为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM