正在包装 C++带有 ctypes 的库是一个坏主意吗?
我通读了以下关于包装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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了捍卫
boost::python
,考虑到 Alexander 对 ctypes 的回答:Boost python 在 c++ 和 python 代码之间提供了非常“c++”接口 - 甚至可以执行允许的 python 子类之类的操作使用 C++ 类来重写虚方法相对简单。以下是一些优秀功能的列表:
std::vector<>
、std::map<>
实例与 Python 列表和字典之间的桥梁(使用vector_indexing_suite
和map_indexing_suite
)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:
std::vector<>
,std::map<>
instances and python lists and dictionaries (usingvector_indexing_suite
andmap_indexing_suite
)boost::shared_ptr
, etc) with python reference counts (and you can extend this to any smart pointer).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.
对于可从 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 asfoo
.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).