如何调用用 C++ 编写的库从C?
在我看来,这似乎是理所当然的事情,但我找不到任何反对或支持它的信息。
从 demangling 等角度来看,我不认为这是一个大问题,但我不知道如何编写一个小小的 C 程序来调用一个小小的 C++ 库中的函数。
我现在在linux上,尝试静态绑定。
这肯定是很多人都遇到过的问题,或者很多书都提到过的问题,但我感觉自己就像一个盲目的阿甘坐在这个问题面前。有趣的是,SO上也没有这样的问题。
我什至不知道这是否可行,更不知道这必须如何完成。
It seems to me like a no-brainer, but I cannot find any information against or for it.
From the point of view of demangling etc, I don't suppose this to be a big problem, but I can't figure out, how I can write a little tiny C program which calls a function from a little tiny C++ library.
I am on linux right now, trying with static binding.
This must be something many people are running into or many books cover, but I feel like a blind gump sitting in front of this problem. Interestingly, there is no such question on SO either.
I do not even know IF this can work, far lesser HOW this has to be done.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
通常,您需要强制 C++ 编译器为导出函数构建具有 C 链接的库。
您可以通过对标头执行以下操作来做到这一点:
通常,链接器将对函数进行 C++ 名称修改,以便 C 链接器无法找到它们。
extern "C"
强制它不这样做。您需要将其包装在#ifdef
中,因为extern "C"
在 C 中无效。更新
正如 Charles Salvia 在在下面的评论中,您需要确保没有异常通过您的接口出去,因为 C 无法处理它们(至少不是独立于平台的方式)。
Typically, you need to force the C++ compiler to build the library with C linkage for the exported functions.
You can do that by doing the following to your header:
Normally, the linker will do C++ name-mangling to the functions, so that the C linker won't be able to find them.
extern "C"
forces it not to do that. You need to wrap it in the#ifdef
, becauseextern "C"
isn't valid in C.UPDATE
As Charles Salvia says in a comment below, you need to ensure that no exceptions make their way out through your interface, because C has no way of handling them (at least not a platform-independent way).
如果 C++ 库不提供 C 接口,那么您就不能。
如果是,则使用 C 接口。
如果您是作者,请使用
extern "C"
功能。 http://www.parashift.com/c++-faq -lite/mixing-c-and-cpp.htmlIf the C++ library does not provide a C interface, then you can't.
If it does, use C interface.
If you are the author, use the
extern "C"
feature. http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html就个人而言,我会编写一个 C++ 文件来导出使用 C 链接的函数。换句话说,编写一个绑定。
Personally, I'd write a C++ file that exports functions that use C linkage. In other words, write a binding.
在 Linux 上,您可以使用命令
Call the function from C by it's mangled name 来获取 C++ 函数的损坏名称,但不要指望这个技巧是可移植的...
编辑:那么您就拥有了使用 g++ 或 gcc -lstdc++ 进行链接
On Linux, you can get the mangled name of your C++ functions with the command
Call the function from C by it's mangled name, but do not expect this trick to be portable...
Edit: then you have to link using g++, or with gcc -lstdc++
从拆解的角度来看,这是一个问题。在要从 C 调用的 C++ 周围使用 extern C 。
重整和反重整从未在 C++ 中标准化,因为它被认为过于依赖于平台。结果是,虽然您可以通过查看链接器输出来找出 C++ 方法的方法名称,但没有可移植的方法来查找 C++ 函数方法的“真实”可链接名称。
It is a problem from the point of demangling. Use extern C around the C++ you want to call from C.
Mangling and de-mangling was never standardized in C++, since it was deemed too platform dependent. The result is, that while you could figure out the method name of a C++ method by looking at the linker output, there is no portable way of finding the "real" linkable name of a C++ method of function.
您可以围绕任何具有 C++ API 的 C++ 库编写 C 包装器。包装器应该用 C++ 编写。
您甚至可以使用 C++ 类。您预先将它们声明为结构体。如果您这样做,某些编译器会发出警告,但您可以禁用此警告或忽略它。
现在,您创建自由函数来创建指向此类结构的指针(不是实例,因为您看不到其完整定义),并通过将其作为参数来处理此类指针及其所有方法。
请注意,如果该类位于命名空间中,您将无法执行此操作,因此请创建自己的仅包含该成员的结构并使用该“包装器”。
适用于所有 C 函数。仅在标题中,放置
You can write a C wrapper around any C++ library that has a C++ API. The wrapper should be written in C++.
You can even use your C++ classes. You forwardly declare them as struct. Some compilers will give a warning if you do this but you can probably either disable this warning or just ignore it.
You now create free-functions to create a pointer to such a struct (not an instance, as you don't see its full definition) and to dispose of such a pointer and all its methods by taking it as a parameter.
Note that if the class is in a namespace, you won't be able to do this so create your own struct that has just that member and use that "wrapper" instead.
For all your C functions. in the header only, put
典型的包装器如下所示:
---- class_a.hpp ----
---- class_a_wrapper.h ----
---- class_a_wrapper.cpp ----
Typical wrapper looks like this:
---- class_a.hpp ----
---- class_a_wrapper.h ----
---- class_a_wrapper.cpp ----