python-C ++扩展可以获得一个C ++对象并调用其成员函数吗?

时间:2015-07-13 19:03:34

标签: python c++ python-extensions

我正在编写一个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()

也欢迎任何对一般阅读的提及。

2 个答案:

答案 0 :(得分:6)

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

有两种主要方法可以解决这个问题。

1.按照CPython API Documentation

中提供的文档自行创建扩展程序

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

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

对于您的示例,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})

答案 1 :(得分:3)

简答:是的,当然。您只需要使用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非常简单且非常轻便。