【问题标题】:Can python-C++ extension get a C++ object and call its member function?python-C++扩展可以获取一个C++对象并调用它的成员函数吗?
【发布时间】:2015-07-13 19:03:33
【问题描述】:

我正在编写一个 python/C++ 应用程序,它将从 python 调用 C++ 扩展中的方法。

假设我的 C++ 有一个类:

class A
{
    private:
        int _i;
    public:
        A(int i){_i=i;}
        int get_i(){return _i;}
}

A a=A();

无论如何,python 可以在 C++ 中获取a 对象并调用其成员函数,即:

import cpp_extension
a=cpp_extension.A()
print a.get_i()

也感谢任何对一般阅读的参考。

【问题讨论】:

    标签: python c++ python-extensions


    【解决方案1】:

    是的。您可以创建一个 Python C++ 扩展,其中您的 C++ 对象将从 Python 中可见,就好像它们是内置类型一样。

    主要有两种方法。

    1.按照CPython API Documentation中提供的文档自行创建扩展。

    2.使用boost::pythonSWIG等工具创建扩展。

    根据我的经验, boost::python 是最好的方法(它可以为您节省大量时间,而且您付出的代价是现在您依赖于 boost)。

    对于您的示例,boost::python 绑定可能如下所示:

    // foo.cpp
    #include <boost/python.hpp>
    
    class A {
    
     public:
    
      A(int i)
          : m_i{i} { }
    
      int get_i() const {
        return m_i;
      }
     private:
      // don't use names such as `_i`; those are reserved for the
      // implementation
      int m_i;
    };
    
    BOOST_PYTHON_MODULE(foo) {
      using namespace boost::python;
    
      class_<A>("A", init<int>())
          .def("get_i", &A::get_i, "This is the docstring for A::get_i")
          ;
    }
    

    编译:

    g++ -o foo.so foo.cpp -std=c++11 -fPIC -shared \
    -Wall -Wextra `python2.7-config --includes --libs` \
    -lboost_python
    

    并在 Python 中运行:

    >>> import foo
    >>> a = foo.A(2)
    >>> a.get_i()
    2
    >>> print a.get_i.__doc__
    
    get_i( (A)arg1) -> int :
        This is the docstring for A::get_i
    
        C++ signature :
            int get_i(A {lvalue})
    

    【讨论】:

    • 谢谢!你能给我一个第一种方法的例子吗,从文档中如何可以从 Python 访问 C++ 类似乎并不明显。
    • @HailiangZhang 一个更简单的方法是编写一个 pyx 文件并将其与 Cython 一起使用。
    • @Himanshu Mishra 我明白,但我正在寻找依赖最少的解决方案。
    • “最少”依赖意味着您想自己编写.c 文件。然后查看使用 C/C++ here 扩展 Python 的文档。但我必须说,这是你不想再做的一件事。来吧。
    • 嗨,你的例子很直观,我是一个 Python 程序员,我写了很少的 C++ 代码,但是这些天,我想用 C++ 编写我的 Python 模块并创建一个.so 文件所以我可以加速我的原始 Python 代码。你认为用 C++ 重写 Python 代码并创建一个从 Python 调用的.so 可以获得很大的加速吗?
    【解决方案2】:

    简短回答:当然可以。您只需要使用 Python 包装器来包装 C++ 代码。

    详细说明:

    假设您的 C++ 代码在 class_file.h 中。在同一目录中,使用您选择的任何名称创建一个 .pxd 文件,其中包含以下内容

    cdef extern from "class_file.h":
        cdef cppclass A:
            int _i
            A(int)
            int get_i
    

    这是 C++ 文件的包装器。这就是您使用 Cython 所要做的一切。此外,您需要编写一个.pyx 文件和cimport 您的pxd 文件,就像一个简单的模块。您还需要有一个setup.py,它将创建一个.so 文件,该文件可以像任何其他python 模块一样由Python 轻松导入。

    如需更多帮助,请访问http://docs.cython.org/src/tutorial/cython_tutorial.html。我希望您发现 Cython 非常简单且基于轻量级。

    【讨论】:

    • 我正在寻找依赖最少的解决方案。
    • 你认为有没有不使用 Cython/booost_python 的快速解决方案?
    • Cython 是可以想象的最快的包装解决方案。查看extending Python with C/C++ 的文档,了解手动完成工作并非易事。 Cython 只需 10-15 行代码即可自动为您生成 .c 包装文件(>10K 行)。
    • 可以避免编写 setup.py 和 pyx 文件。 Cython 在 ipython 中有一个内置的魔法。见docs.cython.org/src/quickstart/…
    • 我很了解 Cython,但我正在寻找没有这种依赖性的解决方案。
    猜你喜欢
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    相关资源
    最近更新 更多