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

发布于 2024-12-04 06:54:31 字数 998 浏览 2 评论 0原文

我有一个混合 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++ 库,但它显然需要一些东西,例如运算符 new/delete 等,并且内部存在例外。

我将这个东西与 Xen 虚拟机管理程序链接起来,所以我不确定我有什么选择,但要完全重写这个东西,或者尝试用 G++ 编译 Xen?

I have a mixed C/C++ library.

On the outside it provides a C interface using extern C. Internally there are templates and classes. Creating the library with "ar" posed no problems. The file is called libo-client.a.

However, when linking the .a file using gcc (not g++) I get lots of errors that look like this:

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.

This problem does not occur when I'm using g++. However, I'm going to interface this library into C project which is compiled with gcc. 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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

久隐师 2024-12-11 06:54:31

解决问题的最简单方法是链接到 g++;这样就可以得到正确的库了。

问题是 C++ 有很多 C 没有的要求,并且在调用 main() 之前做了更多工作以确保正确初始化。

如果您坚持使用 C 编译器链接,至少您必须在链接命令中包含 C++ 支持库。

The simplest way around your problem it is to link with 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.

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.

飞烟轻若梦 2024-12-11 06:54:31

您的 C++ 库在内部仍然是一个 C++ 库,这意味着它包含对 C++ 标准库中的各种内务函数的外部引用。为了解析这些链接,您必须链接 C++ 标准库的最终可执行文件。 gcc 不会自动为您执行此操作。要么显式向 gcc 提供 C++ 标准库,要么使用 g++ 编译器。

Your C++ library is still a C++ library internally, which means that it contains external references to various housekeeping functions from C++ standard library. In order to resolve these links you'll have to link your final executable for C++ standard library. gcc does not do it for you automatically. Either explicitly supply the C++ standard library to gcc, or use g++ compiler instead.

一绘本一梦想 2024-12-11 06:54:31

存档仍然只是一堆目标文件 (.o),因此当将它们链接到可执行文件或共享库时,您仍然需要使用 g++ 链接来将符号解析为 C++ 运行时(例如一旦您在错误消息中看到)。

为了使您的 C 函数具有 C 链接,将它们包装在 extern "C" 块中就足够了。在 Windows 等系统上,事情可能会变得更加复杂,因为它有无数的链接宏(STDCALL、WINAPI 等),这些宏可扩展到其他内容(某些编译器特定的),如 __stdcall、__declspec(export) 等。

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).

For your C functions to have C-linkage, it should be enough to wrap them in extern "C" blocks. Things might get more complicated on, e.g. Windows, with it's myriads of linkage macros (STDCALL, WINAPI, etc.) that expand to other stuff (some compiler specific) like __stdcall, __declspec(export), etc.

柠北森屋 2024-12-11 06:54:31

您看到的错误似乎是由于缺少与标准 C++ 库的链接而出现的,该库具有运算符 new、运算符删除等的符号定义。尝试链接 stdc++gcc $(CFLAGS) $(包括)test2.c libo-client.a -o test2 -lstdc++。 Jonathan Leffler 建议更好的选择是使用 g++ 而不是 gcc

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++. Better option is as suggested by Jonathan Leffler to use g++ instead of gcc

云朵有点甜 2024-12-11 06:54:31

用 C++ 编写可以在 C 中使用而无需任何 C++ 所需的额外功能的东西非常困难。甚至可能依赖于编译器。您的库需要 C++ 运行时,并且在程序中调用 main() 之前初始化 C++ 运行时可能需要特殊支持。当您链接到 C 文件时,您的 chimaera 仍然是一个 C++ 程序,即使它是 main() 以及库之外的所有其他内容。

Writing stuff in C++ that can be used from C without any of the extras C++ requires is very hard. 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. Your chimaera in still a C++ program when you link in C files, even if it is main() and everything else outside your library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文