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

发布于 2024-08-20 09:38:07 字数 598 浏览 1 评论 0原文

我需要包装现有的 C++ 库以便在 Python 中使用。阅读这个关于选择合适的包装方法的答案后在 Python 中使用 C++,我决定使用 Py++。

我浏览了 Py++ 教程,使用教程文件,并且我在 generated.cpp 中得到了预期的输出,但我还没有弄清楚如何才能实际使用生成的代码作为可以在 Python 中导入的扩展。我确信我现在必须编译代码,但是用什么编译呢?我应该使用 bjam 吗?

I have a need to wrap an existing C++ library for use in Python. After reading through this answer on choosing an appropriate method to wrap C++ for use in Python, I decided to go with 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. I'm sure I have to compile the code, now, but with what? Am I supposed to use bjam?

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

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

发布评论

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

评论(3

可是我不能没有你 2024-08-27 09:38:07

Py++ 生成您与 boost::python 一起使用的语法,以在应用程序中生成 python 入口点。
假设 Py++ 一切顺利,您需要下载 Boost 框架,并将 boost 包含目录和 boost::python lib 添加到您的项目中,然后使用 Py++ 生成的 cpp 进行编译。

您可以为您的项目使用任何您想要的构建系统,但 boost 是使用 bjam 构建的。您需要选择是需要静态库还是动态 boost python 库,然后按照构建 boost 此处

如果在 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 不兼容。

Py++ generates you syntax you use along with boost::python to generate python entry points in your app.
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.

You can use whatever build system you want for your project, but boost is built with bjam. You need to choose whether you want a static lib or a dynamic boost python lib then follow the instructions for building boost here.

If on windows, you need to change the extension on your built library from .dll to.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.

One final note, the name given in generated.cpp in this macro:

BOOST_PYTHON_MODULE( -name- )

needs to be the exact name of your project, otherwise python will complain.

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. 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. 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. With just a few simple lines you can have python compile and install your package for you. One downside though is its not IDE compatible for those of us who like developing in visual studio.

怪我闹别瞎闹 2024-08-27 09:38:07

以下答案是由 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++ 测试生成代码、编译、加载新模块并测试功能。所有这些都是在一个独立的过程中完成的。

The following answer was provided to me by Roman Yakovenko on the Python C++-sig mailing list; I'm posting it here, with minor edits, for the benefit of the Stack Overflow community.

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. After this, I prefer to use scons (on Windows and on Linux).

The following is an example of sconstruct file, which is used to compile one of the Py++ unittests (this is generated code too :-) ):

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. You can go even father. Py++ tests generate the code, compile, load the new module and test the functionality. All this is done in a single, stand alone process.

浪推晚风 2024-08-27 09:38:07

我用以下内容编写了一个小 makefile:

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

然后将创建的 .so 加载到 ipython 中来使用它:

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

I wrote a small makefile with the following:

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:

In [1]: import hw
In [2]: a = hw.animal('zebra')
In [3]: a.name()
Out[3]: 'zebra'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文