• 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;
    }
    



  • 相关阅读:
    乐观锁+悲观锁
    python读取大文件处理方式
    ionic集成jPush极光推送
    AngularJs中$http发送post或者get请求,SpringMVC后台接收不到参数值的解决办法
    ionic开发插件之ngCordova配置安装(搬运)
    使用Ionic进行移动端APP开发
    HashMap,LinkedHashMap,TreeMap的区别
    ubuntu下node、npm、bower简易安装
    Mongodb数据更新命令(update、save)
    mongoDb地理空间索引和查询
  • 原文地址:https://www.cnblogs.com/ygxsk/p/7693998.html
Copyright © 2020-2023  润新知