转载注明出处:http://blog.youkuaiyun.com/you_lan_hai/article/details/8597451
// TestPython.cpp : 定义控制台应用程序的入口点。
// author: 游蓝海
// blog: http://blog.youkuaiyun.com/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;
}