我需要包装现有的 C++ 库以在 Python 中使用。在阅读了有关选择合适的方法来包装 C++ 以在 Python 中使用的答案后,我决定使用 Py++。
我使用教程文件浏览了Py++的教程,并在 中获得了预期的输出generated.cpp
,但我还没有弄清楚要做什么才能实际使用生成的代码作为我可以在 Python 中导入的扩展。我确定我现在必须编译代码,但是用什么?我应该使用bjam吗?
Py++ 生成您使用的语法以及 boost::python 以在您的应用程序中生成 python 入口点。假设 Py++ 一切顺利,您需要下载 Boost 框架,并将 boost 包含目录和 boost::python 库添加到您的项目中,然后使用 Py++ 生成的 cpp 进行编译。
你可以为你的项目使用任何你想要的构建系统,但是 boost 是用 bjam 构建的。您需要选择是需要静态库还是动态提升 python 库,然后按照此处构建提升的说明进行操作。
如果在 Windows 上,您需要将构建库的扩展名从 .dll 更改为 .pyd。是的,它需要是一个库项目,这不适用于可执行文件。
然后,将 pyd 放在机器上的 python 可以找到它的地方,然后进入 python 并执行 import [Your-library-name] ,希望一切正常。
最后一点,在该宏中的 generated.cpp 中给出的名称:
BOOST_PYTHON_MODULE( -name- )
必须是您项目的确切名称,否则 python 会抱怨。
不到一个月前,我刚刚经历了这一切,所以我知道这种困惑。
在构建库和测试时,我为使我的 python 扩展非常易于使用而做的一件事是在我的构建环境中自己构建 boost::python 和 python。这样 pyd 就可以准确地到达我想要的位置,并且用户无需安装 python 即可使用我的扩展程序运行。不过,这对于您正在做的事情可能有点过头了。
编辑:如果您希望您的扩展在机器上轻松安装和编译,请查看 python 的setuptools。只需几行简单的代码,您就可以让 python 为您编译和安装您的包。一个缺点是它不兼容我们这些喜欢在 Visual Studio 中开发的人的 IDE。
以下答案是由Roman Yakovenko 在 Python C++-sig 邮件列表中提供给我的;为了 Stack Overflow 社区的利益,我将其发布在这里,稍作修改。
我还没有完全理解答案,但我觉得它为我指明了正确的方向。
生成代码后,您必须对其进行编译。为此,您可以使用自己喜欢的构建系统。我只使用 bjam 来编译 boost。在此之后,我更喜欢使用 scons(在 Windows 和 Linux 上)。
以下是 sconstruct 文件的示例,该文件用于编译 Py++ 单元测试之一(这也是生成的代码 :-)):
import sys
env = Environment()
if 'linux' not in sys.platform:
env['MSVS'] = {'VERSION': ''}
env['MSVS_VERSION'] = ''
Tool('msvc')(env)
t = env.SharedLibrary(
target=r'abstract_classes',
source=[r'/home/roman/language-binding/sources/pyplusplus_dev/unittests/temp/abstract_classes.cpp'],
LIBS=[r"boost_python"],
LIBPATH=[r"", r"/home/roman/include/libs"],
CPPPATH=[
r"/home/roman/boost_svn",
r"/usr/include/python2.6",
r"/home/roman/language-binding/sources/pyplusplus_dev/unittests/temp",
r"/home/roman/language-binding/sources/pyplusplus_dev/unittests/data",
r"/home/roman/boost_svn"
],
CCFLAGS=[ ],
SHLIBPREFIX='',
SHLIBSUFFIX='.so'
)
由于您的代码生成器是用 Python 编写的,因此您可以在 Py++ 停止的地方继续并生成您最喜欢的“make”文件。你甚至可以去父亲。Py++ 测试生成代码、编译、加载新模块并测试功能。所有这些都是在一个独立的过程中完成的。
我写了一个小makefile,内容如下:
GNUmake 文件:
PYTHON_INC=$(shell python-config --includes)
PYTHON_LIBS=$(shell python-config --libs)
BOOST_LIBS=-lboost_python
all:
g++ -W -Wall $(PYTHON_INC) $(PYTHON_LIBS) $(BOOST_LIBS) -fPIC -shared generated.cpp -o hw.so
然后将创建的 .so 加载到 ipython 中以使用它:
In [1]: import hw
In [2]: a = hw.animal('zebra')
In [3]: a.name()
Out[3]: 'zebra'