1、导出函数范例
#include
#include
using namespace std;
int add(int arg1, int arg2)
{
return arg1 + arg2;
}
int sub(int arg1, int arg2)
{
return arg1 - arg2;
}
static PyObject* math_add(PyObject* self, PyObject* args)
{
int arg1, arg2;
if (!PyArg_ParseTuple(args, "ii", &arg1, &arg2))
{
return NULL;
}
int result = add(arg1, arg2);
return (PyObject*)Py_BuildValue("i", result);
}
static PyObject* math_sub(PyObject* self, PyObject* args)
{
int arg1, arg2;
if (!PyArg_ParseTuple(args, "ii", &arg1, &arg2))
{
return NULL;
}
int result = sub(arg1, arg2);
return (PyObject*)Py_BuildValue("i", result);
}
static PyMethodDef MathMethods[] =
{
{ "add", math_add, METH_VARARGS, "Execute math command:add." },
{ "sub", math_sub, METH_VARARGS, "Execute math command:sub." },
{ NULL, NULL }
};
static struct PyModuleDef MathModule =
{
PyModuleDef_HEAD_INIT,
"math_capi",
"example module doc string",
-1,
MathMethods,
NULL,
NULL,
NULL,
NULL
};
static PyObject* __mathError;
PyMODINIT_FUNC
PyInit_Math()
{
PyObject* module = PyModule_Create(&MathModule);
if (NULL == module)
{
return NULL;
}
__mathError = PyErr_NewException("math.error", NULL, NULL);
Py_INCREF(__mathError);
PyModule_AddObject(module, "error", __mathError);
return module;
}
std::string
format_python_traceback(PyObject *tb)
{
PyTracebackObject *trace = (PyTracebackObject*)tb;
std::string stack;
stack = "Traceback:\n";
while (trace && trace->tb_frame)
{
/*PyFrameObject *frame = (PyFrameObject*)trace->tb_frame;
stack += base::strfmt(" File \"%s\", line %i, in %s\n",
PyString_AsString(frame->f_code->co_filename),
trace->tb_lineno,
PyString_AsString(frame->f_code->co_name));
PyObject *code = PyErr_ProgramText(PyString_AsString(frame->f_code->co_filename), trace->tb_lineno);
if (code)
{
stack += base::strfmt(" %s", PyString_AsString(code));
Py_DECREF(code);
}*/
trace = trace->tb_next;
}
return stack;
}
std::string
format_python_exception(std::string &summary)
{
std::string reason, stack;
PyObject *exc, *val, *tb;
PyErr_Fetch(&exc, &val, &tb);
PyErr_NormalizeException(&exc, &val, &tb);
if (val)
{
PyObject *tmp = PyObject_Str(val);
if (tmp)
{
reason = PyBytes_AsString(tmp);
Py_DECREF(tmp);
}
}
if (tb)
stack = format_python_traceback(tb);
else
stack = "No stack information. ";
PyErr_Restore(exc, val, tb);
summary = reason;
return stack + reason+"\n";
}
static std::string
exception_detail()
{
PyObject *exc_class = NULL, *exc = NULL, *exc_tb = NULL;
PyErr_Fetch(&exc_class, &exc, &exc_tb);
if (exc)
{
PyObject *str = PyObject_Str(exc);
if (str)
{
//char *s = PyByteArray_AsString(str);
char *s = PyBytes_AsString(str);
if (s)
return s;
Py_DECREF(str);
}
Py_DECREF(exc);
}
Py_XDECREF(exc_class);
Py_XDECREF(exc_tb);
// PyErr_Restore(exc, val, tb);
return "";
}
// 调用输出"Hello World"函数
void
HelloWorld()
{
PyImport_AppendInittab("math_capi", PyInit_Math);
Py_Initialize();
PyImport_ImportModule("math_capi");
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('.')");
PyRun_SimpleString("sys.path.append('./')");
PyRun_SimpleString("print 'Hello Python!'\n");
PyObject* pModule = PyImport_ImportModule("testpython");
PyErr_Print();
std::string strError = exception_detail();
if (!pModule)
{
return;
}
PyErr_Print();
PyObject* pFunc = PyObject_GetAttrString(pModule, "HelloWorld");
PyErr_Print();
if (pFunc && PyCallable_Check(pFunc))
{
PyObject_CallObject(pFunc, NULL);
}
Py_Finalize();
}
// 调用Add函数,传两个int型参数
void
Add()
{
Py_Initialize();
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
pModule = PyImport_ImportModule("testpython"); // Test:Python文件名
pFunc = PyObject_GetAttrString(pModule, "add"); // Add:Python文件中的函数名
// 创建参数
PyObject* pArgs = PyTuple_New(2); // 函数调用的参数传递均是以元组的形式打包的,2表示参数个数
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 5)); // 0---序号 i表示创建int型变量
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 7)); // 1---序号
// 返回值
PyObject* pReturn = NULL;
pReturn = PyEval_CallObject(pFunc, pArgs); // 调用函数
// 将返回值转换为int类型.
int result;
PyArg_Parse(pReturn, "i", &result); // i表示转换成int型变量
cout << "5+7 = " << result << endl;
Py_Finalize();
}
// 参数传递的类型为字典
void
TestTransferDict()
{
Py_Initialize();
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
pModule = PyImport_ImportModule("testpython"); // Test:Python文件名
pFunc = PyObject_GetAttrString(pModule, "TestDict"); // Add:Python文件中的函数名
// 创建参数
PyObject* pArgs = PyTuple_New(1);
PyObject* pDict = PyDict_New(); // 创建字典类型变量
PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "scott")); // 往字典类型变量中填充数据
PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 18)); // 往字典类型变量中填充数据
PyTuple_SetItem(pArgs, 0, pDict); // 0---序号 将字典类型变量添加到参数元组中
// 返回值
PyObject* pReturn = NULL;
pReturn = PyEval_CallObject(pFunc, pArgs); // 调用函数
// 处理返回值
int size = PyDict_Size(pReturn);
cout << "返回字典的大小为: " << size << endl;
PyObject *pNewAge = PyDict_GetItemString(pReturn, "Age");
int newAge;
PyArg_Parse(pNewAge, "i", &newAge);
cout << "True Age: " << newAge << endl;
Py_Finalize();
}
// 测试类
void
TestClass()
{
Py_Initialize();
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
pModule = PyImport_ImportModule("testpython"); // Test:Python文件名
pFunc = PyObject_GetAttrString(pModule, "TestDict"); // Add:Python文件中的函数名
// 获取Person类
PyObject* pClassPerson = PyObject_GetAttrString(pModule, "Person");
// 创建Person类的实例PyInstance_New
PyObject* pInstancePerson = PyObject_CallObject(pClassPerson,NULL);
// 调用方法
PyObject_CallMethod(pInstancePerson, "greet", "s", "Hello Kitty"); // s表示传递的是字符串,值为"Hello Kitty"
Py_Finalize();
}
int main(int argc, char *argv[])
{
/* 传递argv[0]给Python解释器*/
//Py_SetProgramName(argv[0]);
cout << "Starting Test..." << endl;
cout << "HelloWorld()-------------" << endl;
HelloWorld();
cout << "Add()--------------------" << endl;
Add();
cout << "TestDict-----------------" << endl;
TestTransferDict();
cout << "TestClass----------------" << endl;
TestClass();
system("pause");
return 0;
}
2、编写脚本
#testpython.py
import math_capi
def HelloWorld():
print("Hello World!")
print(math_capi.add(3,5))
print(math_capi.sub(5,3))
def add(a, b):
return a+b
def TestDict(dict):
print(dict)
dict["Age"] = 17
return dict
class Person:
def greet(self, greetStr):
print(greetStr)
#print add(5,7)
#a = raw_input("Enter To Continue...")