简体   繁体   English

为什么我不能使用gcc链接具有C接口的混合C / C ++静态库?

[英]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.

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