导出用于Python的C ++类

时间:2018-09-25 09:38:58

标签: python c++ dll dllexport

我有一个用C ++编写的程序(目前为静态库),具有非常抽象的接口,该接口在类等上使用运算符重载。我想从中创建一个共享库(Windows上的DLL是第一步) ,然后再尝试其他平台)以其他“用户友好”语言使用它。我了解到Python的ctypes对此提供了一定程度的支持。

我只是想知道,在我花时间尝试做某事之前,是否有可能在Python中使用C ++ DLL中的一些高层抽象来选择正确的选项,这是不可能的。用户应该能够初始化我的程序提供的类,并将它们与包括重载运算符在内的所有方法一起使用(当然,只有那些在python中可用)。还是Python仅意味着支持一些简单的函数调用等?

C ++代码(甚至只是用户可访问的类)非常庞大,我想避免创建单独的Python包装器,因为所有必需的功能已经在C ++中完成。

1 个答案:

答案 0 :(得分:0)

由于没有人回答,我将同时提供自己收集的所有内容。希望对某些人有帮助。

Python的ctypes仅支持C语言功能。因此,无法使用ctypes从Python直接访问类和其他C ++对象。但是,有一些访问它们的方法。

乏味的方法

为C ++类创建C样式对象,然后为其创建Python包装器。

C样式对象基本上是动态分配的C ++对象的指针。它应该具有其他方法,例如常规命名为->Release()的方法来破坏对象并释放分配的内存。然后,您将需要手动创建类似于原始C ++对象的python包装器,包括重载的运算符等。(旁注:我遇到的唯一运算符,在这种情况下可能是需要的,在Python中不可重载的是赋值运算符。 )

当您想完全控制正在发生的事情并且不介意在Python中复制接口时,这可能是最好的解决方案。

快速方法

Boost提供了一个Boost :: Python库来处理此问题。它使您几乎可以导出所需的任何内容-类,运算符,甚至多个重载方法。

唯一的问题是,该库非常大,并且是非标头Boost库之一,因此您需要弄清楚如何用您的项目进行构建,这对人们来说可能并不容易,从未与Boost合作的人(像我一样)。

我不知道这个库到底是做什么的,也许它只是自动化了前面方法中描述的事情。因此,我不确定是要减少附加包装的数量,还是只是为您完成所有硬包装的工作,但这确实是我需要做的。

更快的方法

幸运的是,我遇到了一个替代方法-pybind11。这是一个相对较小的库,其功能与Boost :: Python相同,并且仅标头。它具有很好的文档并且易于使用。之所以称其为pybind 11 ,是因为它原本打算支持C ++ 11,但目前支持C ++ 14以及实验性的C ++ 17,但我将其用于C ++ 17项目和到目前为止没有发现任何问题。

我尚不确定哪种方法最适合我的项目,但现在,我使用pybind11只是为了在项目开发过程中使其更容易。