【问题标题】:How to wrap a python class into a C++ class?如何将 python 类包装成 C++ 类?
【发布时间】:2013-12-17 19:53:34
【问题描述】:

我有一个实现给定功能的 python 类,例如文件 Test_script.py 是:

class Test(object):
    def __init__(self,name):
        self.name=name
    def f1(self,n):
        return n**2
    def f2(self,n,m):
        return n+m
    def f3(self,word):
        print word

我如何构建一个简单地包装这个类和所有函数的 C++ 类,以便这个类可以被其他 C++ 类/代码使用? boost::python 是否有助于提供一些快捷方式?

这为什么相关? 因为可以有一些具体的用例,在 python 中实现给定的功能更快、更容易,因为可以重用许多经过良好测试和记录的模块(例如解析、numpy 函数......),而不是从头开始在 C++ 中。上面的类是一个玩具问题,一旦清楚如何在 C++ 中包装/嵌入它,处理更复杂的功能就会很容易。

谢谢

【问题讨论】:

  • 你为什么要这样做?无论问题是什么,这似乎都不是“正确”的解决方案......通常这种类型的事情是将 C/C++ 暴露给 python,反之亦然......(事实上,您可能想要的是暴露 C /C++ 对 python 的功能,python 可以将测试实例传递给。
  • 这些近乎琐碎的函数可以很容易地在 C++ 中实现。真的这么简单吗?
  • @JoranBeasley:事实证明,使用该语言的所有类型和模块,我可以在 python 中更轻松地实现一些功能,例如解析,...所以我认为有些用例只是为了方便而想在 python 中做一些事情
  • @moooeeeep:这是为了让示例简单,实际情况在 C++ 中很难实现,因为我使用了很多 python 函数和数据结构
  • 你可能对这个帖子感兴趣stackoverflow.com/questions/4650243/…

标签: c++ python wrapper


【解决方案1】:

您是否查看过有关在 C++ 应用程序中嵌入 Python 功能的文档?注意 Boost.Python 接口,尤其是 Python Interpreter C API。 (Boost.Python 更加关注用 C++ 编写 Python 扩展,而不是相反。)

供参考:

还可以在此处查看我对 C API 的简单应用的回答(从 C 应用程序中使用 matplotlib):

这是另一个简单的示例,如何使用 C API 从 C++ 应用程序中导入 Python 模块并执行它们的功能。详情请参考文档。

#include <Python.h>
#include <boost/algorithm/string/join.hpp>
#include <vector>
#include <string>
#include <iostream>

int main(int argc, const char** argv) {
    // get data to hash
    if (argc < 2) {
        std::cout << "please add some command line args\n";
        return -1;
    }
    std::string data = boost::algorithm::join(
            std::vector<std::string>(argv+1, argv+argc), " ");
    std::cout << "compute md5 of string: '" << data << "'\n";
    // initialize Python API
    Py_Initialize();
    // import hashlib module
    PyObject *pHashlib = PyImport_ImportModule("hashlib");
    // get hash function
    PyObject *pHashlibMd5 = PyObject_GetAttrString(pHashlib, "md5");
    // build function argument tuple
    PyObject *pFuncParams = PyTuple_New(1);
    PyTuple_SetItem(pFuncParams, 0, PyString_FromString(data.c_str()));
    // call function
    PyObject *pMd5 = PyObject_CallObject(pHashlibMd5, pFuncParams);
    // get function to retrieve hex digest
    PyObject *pMd5Hexdigest = PyObject_GetAttrString(pMd5, "hexdigest");
    // call function
    PyObject *pRet = PyObject_CallObject(pMd5Hexdigest, 0);
    // print result
    std::cout << PyString_AsString(pRet) << "\n";
    // deinitialize
    Py_DECREF(pRet);
    Py_DECREF(pMd5Hexdigest);
    Py_DECREF(pMd5);
    Py_DECREF(pFuncParams);
    Py_DECREF(pHashlibMd5);
    Py_DECREF(pHashlib);
    Py_Finalize();
}

构建并运行:

$ g++ test.cc -I /usr/include/python2.7 -l python2.7
$ ./a.out Hello World
compute md5 of string: 'Hello World'
b10a8db164e0754105b7a99be72e3fe5

比较:

>>> import hashlib
>>> print hashlib.md5('Hello World').hexdigest()
b10a8db164e0754105b7a99be72e3fe5

希望这会有所帮助。

【讨论】:

  • 是的,谢谢,我看到了这些链接,但我觉得这些解释不太有用。我希望找到一个关于包装类的具体示例,boost 文档总是相当简约。我觉得奇怪的是,有很多关于用 C++ 扩展 python 的例子,但相反的例子却很少
  • @Mannaggia 这种不平衡可能是因为一种方法更常见:“最好的方法通常是只用 C++ 或 Java 编写应用程序的性能关键部分,并使用Python 用于所有更高级别的控制和自定义。” (python.org/doc/essays/omg-darpa-mcc-position.html)
  • 是的,就是这样,C++ 中的类只是对象,它们的方法可以用 PyObject_GetAttrString 访问,PyObject_CallObject 可以用来调用类的构造函数或类的其他函数跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 2018-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-26
  • 2012-04-23
相关资源
最近更新 更多