[英]Why can't I link a mixed C/C++ static library that has a C interface using gcc?
I have a mixed C/C++ library. 我有一个混合的C / C ++库。
On the outside it provides a C interface using extern C. Internally there are templates and classes. 在外部它提供了一个使用extern C的C接口。在内部有模板和类。 Creating the library with "ar" posed no problems.
用“ar”创建库没有任何问题。 The file is called libo-client.a.
该文件名为libo-client.a。
However, when linking the .a
file using gcc (not g++) I get lots of errors that look like this: 但是,当使用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'
...
My compile/link line looks like this: 我的编译/链接行如下所示:
gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2
Where test2 is my test harness. test2是我的测试工具。
This problem does not occur when I'm using g++. 当我使用g ++时,不会发生此问题。 However, I'm going to interface this library into C project which is compiled with gcc.
但是,我要将这个库连接到用gcc编译的C项目中。 How do I get around this?
我该如何解决这个问题? What's the cause of it?
它的原因是什么?
EDIT: 编辑:
Even though I'm not using the standard C++ library it's obviously needing some things like operator new/delete etc. and there are exceptions internally. 即使我没有使用标准C ++库,显然还需要一些诸如operator new / delete等内容,并且内部存在异常。
I'm linking this thing against the Xen hypervisor so I'm not sure what options i have but to totally rewrite this thing or perhaps try compiling Xen with G++ instead? 我将这个东西与Xen管理程序相关联,所以我不确定我有什么选择,但要完全改写这个东西,或者尝试用G ++编译Xen?
The simplest way around your problem it is to link with g++
; 解决问题的最简单方法是使用
g++
进行链接; this gets the correct libraries in place. 这将获得正确的库。
The problem is that C++ has a lot of requirements that C does not, and does more work before calling main()
to ensure that things are properly initialized. 问题是C ++有许多要求,C没有,并且在调用
main()
之前做了更多的工作,以确保事情被正确初始化。
If you insist on linking with the C compiler, at the very least you'd have to include the C++ support library in with your link command. 如果您坚持使用C编译器进行链接,那么至少您必须使用link命令包含C ++支持库。
Your C++ library is still a C++ library internally, which means that it contains external references to various housekeeping functions from C++ standard library. 您的C ++库在内部仍然是一个C ++库,这意味着它包含来自C ++标准库的各种内务处理函数的外部引用。 In order to resolve these links you'll have to link your final executable for C++ standard library.
为了解决这些链接,您必须链接C ++标准库的最终可执行文件。
gcc
does not do it for you automatically. gcc
不会自动为你做这件事。 Either explicitly supply the C++ standard library to gcc
, or use g++
compiler instead. 要么明确地将C ++标准库提供给
gcc
,要么使用g++
编译器。
An archive is still just a bunch of object files (.o), so when linking them into an executable or shared library, you still need to link with g++
to resolve symbols to the C++ runtime (like the once you see in your error messages). 归档文件仍然只是一堆目标文件(.o),因此在将它们链接到可执行文件或共享库时,仍然需要与
g++
链接以将符号解析为C ++运行时(就像您在错误消息中看到的那样) )。
For your C functions to have C-linkage, it should be enough to wrap them in extern "C"
blocks. 为了使C函数具有C-linkage,它应该足以将它们包装在
extern "C"
块中。 Things might get more complicated on, eg Windows, with it's myriads of linkage macros (STDCALL, WINAPI, etc.) that expand to other stuff (some compiler specific) like __stdcall, __declspec(export), etc. 事情可能会变得更加复杂,例如Windows,它的无数链接宏(STDCALL,WINAPI等)扩展到其他东西(某些特定于编译器),如__stdcall,__ declspec(导出)等。
The errors which you see seem to appear due to missing linkage to Standard C++ library which has the symbol definition for operator new, operator delete etc. Try linking stdc++
say gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 -lstdc++
. 您看到的错误似乎是由于缺少与标准C ++库的链接而出现的,该库具有operator new,operator delete等的符号定义。尝试链接
stdc++
说gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 -lstdc++
。 Better option is as suggested by Jonathan Leffler to use g++
instead of gcc
更好的选择是由Jonathan Leffler建议使用
g++
而不是gcc
Writing stuff in C++ that can be used from C without any of the extras C++ requires is very hard . 用C语言编写可以在没有任何C ++要求的情况下从C使用的东西非常困难 。 Probably even compiler dependent.
甚至可能依赖于编译器。 Your library requires the C++ runtime, and to initialize the C++ runtime presumaby requires special support before caling main() in your program.
您的库需要C ++运行时,并且在程序中调用main()之前需要特殊支持来初始化C ++运行时presuma。 Your chimaera in still a C++ program when you link in C files, even if it is main() and everything else outside your library.
当你链接C文件时,你的chimaera仍然是一个C ++程序,即使它是main()和你库外的其他东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.