2013-12-17 24 views
2

我有实现给定功能的Python类,例如文件Test_script.py是:如何将python类包装到C++类中?

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++包装/嵌入它,将很容易处理更复杂的功能。

THX

+0

你为什么要这样做?对于任何问题,这似乎并不是什么“正确”的解决方案......通常这种类型的事情是将C/C++暴露给python,而不是相反......(实际上,这可能是你想要暴露C/C++功能python可以比通过测试实例。 –

+0

这些接近平凡的功能可以很容易地在C++中实现。它真的很简单吗? – moooeeeep

+0

@JoranBeasley:事实证明,有一些功能,我可以实现使用这种语言的所有类型和模块,例如解析,在Python中更容易...所以我认为有些用例只是为了方便而想在python中做些什么 – Mannaggia

回答

4

你有没有抬头的文档在C++应用程序中嵌入Python的功能?注意Boost.Python接口,特别是Python解释器C API。 (Boost.Python的将更多的焦点上用C写作Python扩展++而不是周围的其他方法。)

参考:

也看看我的答案这里的C API的一个简单的应用程序(使用matplotlib从C应用):

这里还有一个简单的例子,如何在C API可用于导入Python模块和执行他们的函数来自C++应用程序。有关详细信息,请参阅文档。

#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 

希望这有助于。

+0

是的,谢谢,我看到了这些链接,我没有找到这些解释如此有用。我希望找到关于包装课程的具体示例,助推文档总是相当简约。我发现奇怪的是有很多关于使用C++扩展python的例子,但相反情况很罕见 – Mannaggia

+0

@Mannaggia这种不平衡可能是因为这种方法更常见:_“最好的方法通常只写性能 - 在C++或Java中的应用程序的关键部分,并使用Python进行所有更高级别的控制和定制。“_(http://www.python.org/doc/essays/omg-darpa-mcc-position.html) – moooeeeep

+0

是的,这是要走的路,C++中的类只是对象,可以使用PyObject_GetAttrString访问它们的方法,并且可以使用PyObject_CallObject调用类或类的其他函数的构造函数 – Mannaggia