Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 使用C/C++写Python模块

最近看开源项目时学习了一下用C/C++写python模块,顺便把学习进行一下总结,废话少说直接开始:环境:Windows、python2.78、VS2010或MingW

1 创建VC工程

(1) 打开VC6.0或VS2008,然后File-->New-->Project-->Win32 DLL Project。建立一个Empty Project,比如testClass,一路确定。(2) 之后向工程添加python头文件目录及库文件目录,如头文件目录:F:python278include,库文件目录:F:python278libs(3) 添加一个C++或C源文件,如工程中有用到类,则添加的必须是C++文件,这里直接添加main.cpp #include <Python.h>#include <iostream>#include <sstream>#include <structmember.h>#include <windows.h>using namespace std;typedef struct _CScore{PyObject_HEADchar *m_szName;float m_dMath;float m_dEnglish;}CScore;static PyMemberDef CScore_DataMembers[] = {//类/结构的数据成员的说明.{"m_szName", T_STRING, offsetof(CScore, m_szName), 0, "The Name of instance"},{"m_dMath",T_FLOAT,offsetof(CScore, m_dMath),0, "The Math score of instance."},{"m_dEnglish", T_FLOAT,offsetof(CScore, m_dEnglish), 0, "The English score of instance."},{NULL, NULL, NULL, 0, NULL}};//////////////////////////////////////////////////////////////// CScore类的所有内置、构造方法.//static void CScore_init(CScore* Self, PyObject* pArgs)//构造方法.{const char* Name = 0;if(!PyArg_ParseTuple(pArgs, "sff", &Name, &Self->m_dMath, &Self->m_dEnglish)){cout<<"Parse the argument FAILED! You should pass correct values!"<<endl;return ;}Self->m_szName = new char[strlen(Name) + 1];strcpy(Self->m_szName, Name);}static void CScore_Destruct(CScore* Self) //析构方法.{if(Self->m_szName){delete [] Self->m_szName;//先释放其字符指针对象.}OutputDebugString(TEXT("destroy!!!"));//如果还有PyObject*成员的话,要一并释放之.//如:Py_XDECREF(Self->Member);Py_TYPE(Self)->tp_free((PyObject*)Self);//释放对象/实例.}static PyObject* CScore_Str(CScore* Self)//调用str/print时自动调用此函数.{ostringstream OStr;OStr<<"Name: "<<Self->m_szName<<endl<<"Math: "<<Self->m_dMath<<endl<<"English : "<<Self->m_dEnglish<<endl;string Str = OStr.str();return Py_BuildValue("s", Str.c_str());}static PyObject* CScore_Repr(CScore* Self)//调用repr内置函数时自动调用.{return CScore_Str(Self);}////////////////////////////////////////////////////////////// CScore类的所有Get方法.//static PyObject* CScore_GetName(CScore* Self){return Py_BuildValue("s", Self->m_szName);}static PyObject* CScore_GetMath(CScore* Self){return Py_BuildValue("f", Self->m_dMath);}static PyObject* CScore_GetEnglish(CScore* Self){return Py_BuildValue("f", Self->m_dEnglish);}////////////////////////////////////////////////////////////// CScore类的所有Set方法.//static PyObject* CScore_SetMath(CScore* Self, PyObject* Argvs){Py_INCREF(Py_None);if(!PyArg_ParseTuple(Argvs, "f", &Self->m_dMath)){cout<<"Parse the argument FAILED! You should pass correct values!"<<endl;return Py_None;}return Py_None;}static PyObject* CScore_SetEnglish(CScore* Self, PyObject* Argvs){Py_INCREF(Py_None);if(!PyArg_ParseTuple(Argvs, "f", &Self->m_dEnglish)){cout<<"Parse the argument FAILED! You should pass correct values!"<<endl;return Py_None;}return Py_None;}static PyObject* CScore_PrintInfo(CScore* Self){cout<<"The scores as follows:"<<endl<<"=============================="<<endl<<"Name: "<<Self->m_szName<<endl<<"Math: "<<Self->m_dMath<<endl<<"English : "<<Self->m_dEnglish<<endl<<"=============================="<<endl;Py_XINCREF(Py_None);return Py_None;}static PyMethodDef CScore_MethodMembers[] =//类的所有成员函数结构列表.{{"GetName",(PyCFunction)CScore_GetName, METH_NOARGS, "Get the name of instance."},{"GetMath",(PyCFunction)CScore_GetMath, METH_NOARGS, "Get the math score of instance."},{"GetEnglish", (PyCFunction)CScore_GetEnglish, METH_NOARGS,"Get the english score of isntance."},{"SetMath",(PyCFunction)CScore_SetMath, METH_VARARGS,"Set the math score of instance."},{"SetEnglish", (PyCFunction)CScore_SetEnglish, METH_VARARGS, "Set the english of instance."},{"PrintInfo",(PyCFunction)CScore_PrintInfo, METH_NOARGS, "Print all information of instance."},{NULL, NULL, NULL, NULL}};////////////////////////////////////////////////////////////// 类/结构的所有成员、内置属性的说明信息.//static PyTypeObject CScore_ClassInfo ={PyVarObject_HEAD_INIT(NULL, 0)"Module.MyCppClass",//可以通过__class__获得这个字符串. CPP可以用类.__name__获取.sizeof(CScore), //类/结构的长度.调用PyObject_New时需要知道其大小.0,(destructor)CScore_Destruct,//类的析构函数.0,0,0,0,(reprfunc)CScore_Repr,//repr 内置函数调用。0,0,0,0,0,(reprfunc)CScore_Str,//Str/print内置函数调用.0,0,0,Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //如果没有提供方法的话,为Py_TPFLAGS_DEFAULE"MyCppClass Objects---Extensioned by C++!", //__doc__,类/结构的DocString.0,0,0,0,0,0,CScore_MethodMembers,//类的所有方法集合.CScore_DataMembers,//类的所有数据成员集合.0,0,0,0,0,0,(initproc)CScore_init,//类的构造函数.0,};////////////////////////////////////////////////////////////// 此模块的说明信息. 由于我用的python2所以直接把该部分进行注释///*static PyModuleDef ModuleInfo ={PyModuleDef_HEAD_INIT,"My C++ Class Module", //模块的内置名--__name__."This Module Created By C++--extension a class to Python!", //模块的DocString.__doc__-1,NULL, NULL, NULL, NULL, NULL};*/int add(int x, int y){return x+y;}static PyObject* W_add(PyObject* self, PyObject* args) {int x;int y;if(!PyArg_ParseTuple(args, "i|i", &x, &y)) {return NULL;} else {return Py_BuildValue("i", add(x, y));}}static PyMethodDef module_methods[] = {{"add", W_add, METH_VARARGS, "a function from C"},{NULL, NULL, 0, NULL}};PyMODINIT_FUNC inittestClass(void) //模块外部名称为--CppClass{PyObject* pReturn = 0;CScore_ClassInfo.tp_new = PyType_GenericNew; //此类的new内置函数—建立对象./////////////////////////////////////////////////////// 完成对象类型的初始化—包括添加其继承特性等等。// 如果成功,则返回0,否则返回-1并抛出异常.if(PyType_Ready(&CScore_ClassInfo) < 0)return;pReturn = Py_InitModule3("testClass", module_methods, "Example module that creates an extension type.");if(pReturn == NULL)return;Py_INCREF(&CScore_ClassInfo);PyModule_AddObject(pReturn, "CScore", (PyObject*)&CScore_ClassInfo); //将这个类加入到模块的Dictionary中.return;}main.cpp之后修改VC工程导出文件后缀名为pyd 

2 使用testClass模块

编译工程生成testClass.pyd模块文件,进入到导出文件目录,并启动python导入testClass模块并查看其详细信息模块详细使用更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2016-07/133126p2.htm