简体   繁体   English

使用Py ++生成的代码作为Python扩展

[英]Using code generated by Py++ as a Python extension

I have a need to wrap an existing C++ library for use in Python. 我需要包装一个现有的C ++库以便在Python中使用。 After reading through this answer on choosing an appropriate method to wrap C++ for use in Python , I decided to go with Py++. 在阅读了关于选择适当的方法来包装C ++以便在Python中使用的答案之后,我决定使用Py ++。

I walked through the tutorial for Py++ , using the tutorial files, and I got the expected output in generated.cpp , but I haven't figured out what to do in order to actually use the generated code as an extension I can import in Python. 我使用教程文件浏览了Py ++教程,我在generated.cpp得到了预期的输出,但我还没想出要做什么才能真正使用生成的代码作为我可以在Python中导入的扩展。 I'm sure I have to compile the code, now, but with what? 我确定我现在必须编译代码,但是用什么? Am I supposed to use bjam ? 我应该使用bjam吗?

Py++ generates you syntax you use along with boost::python to generate python entry points in your app. Py ++生成您与boost :: python一起使用的语法,以在您的应用程序中生成python入口点。 Assuming everything went well with Py++ you need to download the Boost framework, and add the boost include directory and the boost::python lib to your project then compile with the Py++ generated cpp. 假设Py ++的一切顺利,你需要下载Boost框架,并将boost include目录和boost :: python lib添加到你的项目中,然后使用Py ++生成的cpp进行编译。

You can use whatever build system you want for your project, but boost is built with bjam. 您可以使用您想要的任何构建系统,但是使用bjam构建boost。 You need to choose whether you want a static lib or a dynamic boost python lib then follow the instructions for building boost here . 你需要选择是否要静态库或则动态升压蟒蛇LIB请按照制作提振说明这里

If on windows, you need to change the extension on your built library from .dll to.pyd. 如果在Windows上,则需要将构建库中的扩展名从.dll更改为.pyd。 And yes it needs to be a library project, this does not work with executables. 是的,它需要是一个库项目,这不适用于可执行文件。

Then, place the pyd where the python on your machine can find it and go into python and execute import [Your-library-name] and hopefully everything will work. 然后,将pyd放在你的机器上的python可以找到它并进入python并执行import [Your-library-name]并希望一切都能正常工作。

One final note, the name given in generated.cpp in this macro: 最后一点,在这个宏中的generated.cpp中给出的名称:

BOOST_PYTHON_MODULE( -name- )

needs to be the exact name of your project, otherwise python will complain. 需要是项目的确切名称,否则python会抱怨。

I just went through all this less than a month ago so I know about the confusion. 我不到一个月前就完成了这一切,所以我知道这种混乱。

One thing I did to make my python extension very easy to use while building the library and testing, was to build boost::python and python myself in my build environment. 我在构建库和测试时使用python扩展非常容易的一件事就是在我的构建环境中自己构建boost :: python和python。 That way the pyd ends up exactly where I want it and users do not need to install python in order to run with my extension. 这样,pyd就会到达我想要的位置,并且用户不需要安装python就可以使用我的扩展程序运行。 That may be overkill for what you are doing though. 虽然这对你正在做的事情可能有点过分。

Edit: If you want your extension to be easily installed and compiled on a machine, check out python's setuptools . 编辑:如果您希望在计算机上轻松安装和编译扩展,请查看python的setuptools With just a few simple lines you can have python compile and install your package for you. 只需几行简单的线条,您就可以编译python并为您安装包。 One downside though is its not IDE compatible for those of us who like developing in visual studio. 一个缺点是它不适合我们这些喜欢在visual studio中开发的人。

The following answer was provided to me by Roman Yakovenko on the Python C++-sig mailing list ; Roman Yakovenko在Python C ++ - sig邮件列表中提供了以下答案; I'm posting it here, with minor edits, for the benefit of the Stack Overflow community. 为了Stack Overflow社区的利益,我在这里发布了一些小编辑。

I don't fully comprehend the answer yet, but I felt it points me in the right direction. 我还没有完全理解答案,但我觉得它指向了正确的方向。


After you have generated the code, you have to compile it. 生成代码后,必须编译它。 For this purpose, you can use your favorite build system. 为此,您可以使用自己喜欢的构建系统。 I use bjam only to compile boost. 我只使用bjam来编译boost。 After this, I prefer to use scons (on Windows and on Linux). 在此之后,我更喜欢使用scons(在Windows和Linux上)。

The following is an example of sconstruct file, which is used to compile one of the Py++ unittests (this is generated code too :-) ): 以下是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'
)

Since your code generator written in Python, you can continue where Py++ stops and generate your favorite "make" file. 由于您的代码生成器是用Python编写的,因此可以继续Py ++停止并生成您喜欢的“make”文件。 You can go even father. 你甚至可以去做父亲。 Py++ tests generate the code, compile, load the new module and test the functionality. Py ++测试生成代码,编译,加载新模块并测试功能。 All this is done in a single, stand alone process. 所有这些都是在一个单独的过程中完成的。

I wrote a small makefile with the following: 我用以下内容编写了一个小的makefile:

GNUmakefile: GNUmakefile:

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

and then loaded the created .so into ipython to play around with it: 然后将创建的.so加载到ipython中来玩它:

In [1]: import hw
In [2]: a = hw.animal('zebra')
In [3]: a.name()
Out[3]: 'zebra'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM