python扩展:包装C++类
转载注明出处:http://blog.csdn.net/you_lan_hai/article/details/8597451
// TestPython.cpp : 定义控制台应用程序的入口点。 // author: 游蓝海 // blog: http://blog.csdn.net/you_lan_hai #include "stdafx.h" #include <iostream> using namespace std; #include "../python/Include/Python.h" #include "../python/Include/structmember.h" //有多个参数的python导出函数 static PyObject* py_test(PyObject* self, PyObject * args) { cout<<"this message comes from C++"<<endl; Py_IncRef(Py_None); return Py_None; } //方法定义 static PyMethodDef lazyMethods[] = { {"test", PyCFunction(py_test), METH_VARARGS, "just for test"}, {NULL, NULL, NULL, NULL}, //结束标志 }; //python导出类 class TestPyClass : public PyObject { public: TestPyClass(PyTypeObject * pType) : id_(0) , score_(99) { if(PyType_Ready(pType) < 0) { cout<<"PyType_Ready faild."<<endl; } PyObject_INIT(this, pType); } virtual ~TestPyClass() { } static PyObject* py_new(PyTypeObject * pType, PyObject *, PyObject *) { return new TestPyClass(pType); } static void py_dealloc(PyObject * self) { delete (TestPyClass*)self; } //init方法。 static int py_init(PyObject * self, PyObject * args, PyObject *) { TestPyClass* pThis = (TestPyClass*)self; if(!PyArg_ParseTuple(args, "ii", &pThis->id_, &pThis->score_)) { return 0; } return 1; } PyObject* py_test(PyObject * args) { cout<<"this message comes from TestPyClass."<<endl; Py_IncRef(Py_None); return Py_None; } //导出函数 static PyObject* _py_test(PyObject* self, PyObject * args) { return ((TestPyClass*)self)->py_test(args); } int id_; int score_; }; /*如果类中有虚函数,则类对象开始地址为一个虚函数表的地址。 由于PyObject没有虚函数,而子类有虚函数,则子类与基类不共起始地址。 */ #define offsetofVirtual(type, member) ( (int) & ((type*)0) -> member - sizeof(void*)) //成员变量 static PyMemberDef TestClassMembers[] = { {"id", T_INT, offsetofVirtual(TestPyClass, id_), 0, "id"}, {"score", T_INT, offsetofVirtual(TestPyClass, score_), 0, "score"}, {NULL, NULL, NULL, 0, NULL}, }; //成员函数 static PyMethodDef TestClassMethods[] = { {"test", PyCFunction(TestPyClass::_py_test), METH_VARARGS, "just for test"}, {NULL, NULL, NULL, NULL}, }; //类类型 static PyTypeObject TestPyClass_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "TestPyClass", sizeof(TestPyClass), 0, (destructor)TestPyClass::py_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ TestClassMethods, /* tp_methods */ TestClassMembers, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)TestPyClass::py_init, /* tp_init */ 0, /* tp_alloc */ (newfunc)TestPyClass::py_new, /* tp_new */ 0, /* tp_free */ }; void initLazy(void) { PyObject* pModule = Py_InitModule("Lazy", lazyMethods); if (pModule) { Py_IncRef((PyObject*)&TestPyClass_Type); PyModule_AddObject(pModule, "TestClass", (PyObject*)&TestPyClass_Type); } } int _tmain(int argc, _TCHAR* argv[]) { Py_SetPythonHome("F:/workspace/test/python"); Py_Initialize(); if (!Py_IsInitialized()) { cout<<"Py_Initialize faild! "<<endl; PyErr_Print(); return 0; } cout<<"Python initialize success."<<endl; initLazy(); PyRun_SimpleString("import Lazy"); PyRun_SimpleString("Lazy.test()"); PyRun_SimpleString("a = Lazy.TestClass(2, 3)"); PyRun_SimpleString("print dir(a)"); PyRun_SimpleString("a.test()"); PyRun_SimpleString("print 'a.id = ', a.id, ', a.score = ', a.score"); #if 0 //测试对象大小。含虚函数的类,会大4个字节。 cout<<"sizeof(PyObject)"<<sizeof(PyObject)<<endl; cout<<"sizeof(TestPyClass)"<<sizeof(TestPyClass)<<endl; TestPyClass testPy(&TestPyClass_Type); cout<<"testPy addr:"<<&testPy<<" "<<(PyObject*)&testPy <<", id:"<<&(((TestPyClass*)0)->id_)<<endl; #endif Py_Finalize(); return 0; }