正在包装 C++带有 ctypes 的库是一个坏主意吗?

发布于 2025-01-01 06:56:21 字数 430 浏览 4 评论 0原文

我通读了以下关于包装C库 和 C++ 库,我是不确定我明白了。我正在使用的 C++ 库确实使用了类和模板,但没有以任何过于复杂的方式。用 ctypes 包装它有什么问题或注意事项(除了可以在纯 python 等中这样做之外)?

PyCXX 、 Cython 和 boost::python 是人们提到的另外三个选择,是否有共识哪一个更适合 C++?

谢谢

奥利弗

I read through the following two threads on wrapping C library and C++ library, I am not sure I get it yet. The C++ library I am working with does use class and template, but not in any over-sophisticated way. What are issues or caveats of wrapping it with ctypes (besides the point that you can do so in pure python etc)?

PyCXX , Cython and boost::python are three other choices people mentioned, is there any consensus which one is more suitable for C++?

Thanks

Oliver

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

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

发布评论

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

评论(2

樱花细雨 2025-01-08 06:56:21

为了捍卫 boost::python,考虑到 Alexander 对 ctypes 的回答:

Boost python 在 c++ 和 python 代码之间提供了非常“c++”接口 - 甚至可以执行允许的 python 子类之类的操作使用 C++ 类来重写虚方法相对简单。以下是一些优秀功能的列表:

  • 允许 Python 子类覆盖 C++ 类的虚拟方法。
  • std::vector<>std::map<> 实例与 Python 列表和字典之间的桥梁(使用 vector_indexing_suitemap_indexing_suite
  • 使用Python引用计数自动共享智能指针(boost::shared_ptr等)中的引用计数(并且您可以将其扩展到任何智能指针)指针)。
  • 传递参数和从函数返回值时对所有权进行细粒度控制。

基本上,如果您的设计希望以忠实于语言的方式公开 C++ 接口,那么 boost::python 可能是最好的方法。

唯一的缺点是增加了编译时间(boost::python 广泛使用模板),并且如果您没有完全正确地处理事情,有时会出现不透明的错误消息。

In defence of boost::python, given Alexander's answer on ctypes:

Boost python provides a very "c++" interface between c++ and python code - even doing things like allowed python subclasses of c++ classes to override virtual methods is relatively straightforward. Here's a potted list of good features:

  • Allow virtual methods of C++ classes to be overridden by python subclasses.
  • Bridge between std::vector<>, std::map<> instances and python lists and dictionaries (using vector_indexing_suite and map_indexing_suite)
  • Automatic sharing of reference counts in smart pointers (boost::shared_ptr, etc) with python reference counts (and you can extend this to any smart pointer).
  • Fine grained control of ownership when passing arguments and returning values from functions.

Basically, if you have a design where you want to expose a c++ interface in a way faithful to the language, then boost::python is probably the best way to do it.

The only downsides are increased compile time (boost::python makes extensive use of templates), and sometimes opaque error messages if you don't get things quite right.

最初的梦 2025-01-08 06:56:21

对于可从 Python 访问的 C++ 库,它必须使用 C 导出名称,这基本上意味着名为 foo 的函数可以作为 foo 从 ctypes 访问。

这只能通过使用 export C {} 封装公共接口来实现,这反过来又不允许其中的函数重载和模板(仅要包装库的公共接口)是相关的,内部工作原理不是,并且可以使用他们喜欢的任何 C++ 功能)。

原因是 C++ 编译器使用一种称为“名称修改”的机制来为重载或模板化符号生成唯一名称。虽然如果您知道函数的重整名称,ctypes 仍然会找到该函数,但重整方案取决于所使用的编译器/链接器,并且您不能依赖它。 简而言之:不要使用 ctypes 来包装在其公共接口中使用 C++ 功能的库

Cython 采用了不同的方法。它可以帮助您构建与原始库进行接口的 C 扩展模块。因此,通过常规C++链接机制来链接到C++库,从而避免了上述问题。 Cython 的问题在于,需要为每个平台重新编译 C 扩展库,但无论如何,这也适用于要包装的 C++ 库。

就我个人而言,我想说,在大多数情况下,与 ctypes 相比,启动 Cython 的时间是值得的,并且最终会得到回报(除了非常简单的 Cish 接口)。

我没有任何使用 boost.python 的经验,所以我无法对它发表评论(但是,我也不认为它很受欢迎)。

For C++ a library to be accessible from Python it must use C export names, which basically means that a function named foo will be accessible from ctypes as foo.

This can be achieved only by enclosing the public interface with export C {}, which in turn disallows function overloading and templates therein (only the public interface of the library to be wrapped is relevant, the inner workings are not and may use any C++ features they like).

Reason for this is that C++ compilers use a mechanism called name mangling to generate unique names for overloaded or templated symbols. While ctypes would still find a function provided you knew its mangled name, the mangling scheme depends on the compiler/linker being used and is nothing you can rely on. In short: do not use ctypes to wrap libraries that use C++ features in their public interface.

Cython takes a different approach. It aids you at building a C extension module that does the interfacing with the original library. Therefore, linking to the C++ library is done by the regular C++ linkage mechanism, thus avoiding the aforementioned problem. The trouble with Cython is that C extension libraries need to to be recompiled for every platform, but anyway, this applies to the C++ library to be wrapped as well.

Personally, I'd say that in most cases the time to fire up Cython is a time that is well-spent and will eventually pay off in comparison to ctypes (with an exception for really simple Cish interfaces).

I don't have any experience with boost.python, so I can't comment on it (however, I don't have the impression that it is very popular either).

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