【问题标题】:Using code generated by Py++ as a Python extension使用 Py++ 生成的代码作为 Python 扩展
【发布时间】:2010-01-30 23:37:52
【问题描述】:

我需要包装现有的 C++ 库以在 Python 中使用。在阅读了this answer on choosing an appropriate method to wrap C++ for use in Python 之后,我决定使用 Py++。

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

【问题讨论】:

  • 你看到Py++作者的这个公告了吗? mail.python.org/pipermail/cplusplus-sig/2009-January/…
  • 我有,但在回答我的问题之前它仍然结束:“最后一步 - 生成代码。”我认为最后一步应该让用户获得可编译和可导入的代码,而不仅仅是生成的。

标签: c++ python word-wrap py++


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    以下答案由Roman Yakovenko on the Python C++-sig mailing list提供给我;为了 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++ 测试生成代码、编译、加载新模块并测试功能。所有这些都在一个独立的过程中完成。

    【讨论】:

      【解决方案3】:

      我写了一个小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'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-10
        • 1970-01-01
        • 2011-05-08
        • 1970-01-01
        • 1970-01-01
        • 2013-02-24
        • 1970-01-01
        • 2010-12-20
        相关资源
        最近更新 更多