中标麒麟(linux)下Qt调用python
转自:https://blog.csdn.net/lwlgzy/article/details/83857297
http://www.cnblogs.com/jiaping/p/6321859.html
https://www.cnblogs.com/lvpengms/archive/2010/02/03/1663071.html
https://www.jb51.net/article/64094.htm
linux下安装qt请看:https://www.cnblogs.com/kimyeee/p/7250560.html
#include <stdio.h> #include <Python.h> int main(int argc, char* argv[]) { PyObject *modulename, *module, *dic, *func, *args, *rel, *list; char *funcname1 = "sum"; char *funcname2 = "strsplit"; int i; Py_ssize_t s; printf("-==在C中嵌入Python==-\n"); /* Python解释器的初始化*/ Py_Initialize(); if(!Py_IsInitialized()) { printf("初始化失败!"); return -1; } PyRun_SimpleString("import sys");//导入模块 PyRun_SimpleString("sys.path.append('./')");//路径 /* 导入Python模块,并检验是否正确导入 */ modulename = Py_BuildValue("s", "pytest");//pytest.py文件放在可执行文件夹下 module = PyImport_Import(modulename); if(!module) { printf("导入pytest失败!"); return -1; } /* 获得模块中函数并检验其有效性 */ dic = PyModule_GetDict(module); if(!dic) { printf("错误!\n"); return -1; } /* 获得sum函数地址并验证 */ func = PyDict_GetItemString(dic,funcname1); if(!PyCallable_Check(func)) { printf("不能找到函数 %s",funcname1); return -1; } /* 构建列表 */ list = PyList_New(5); printf("使用Python中的sum函数求解下列数之和\n"); for (i = 0; i < 5; i++) { printf("%d\t",i); PyList_SetItem(list,i,Py_BuildValue("i",i)); } printf("\n"); /* 构建sum函数的参数元组*/ args = PyTuple_New(1); PyTuple_SetItem(args,0,list); /* 调用sum函数 */ PyObject_CallObject(func,args); /* 获得strsplit函数地址并验证*/ func = PyDict_GetItemString(dic,funcname2); if(!PyCallable_Check(func)) { printf("不能找到函数 %s",funcname2); return -1; } /* 构建strsplit函数的参数元组 */ args = PyTuple_New(2); printf("使用Python中的函数分割以下字符串:\n"); printf("this is an example\n"); PyTuple_SetItem(args,0,Py_BuildValue("s","this is an example")); PyTuple_SetItem(args,1,Py_BuildValue("s"," ")); /* 调用strsplit函数并获得返回值 */ rel = PyObject_CallObject(func, args); s = PyList_Size(rel); printf("结果如下所示:\n"); for ( i = 0; i < s; i ++) { printf("%s\n",PyString_AsString(PyList_GetItem(rel,i))); } /* 释放资源 */ Py_DECREF(list); Py_DECREF(args); Py_DECREF(module); /* 结束Python解释器 */ Py_Finalize(); printf("按回车键退出程序:\n"); getchar(); return 0; }
2.3 数据类型
Python定义了六种数据类型:整型、浮点型、字符串、元组、列表和字典,在使用C语言对Python进行功能扩展时,首先要了解如何在C和Python的数据类型间进行转化。
2.3.1 整型、浮点型和字符串
在Python的C语言扩展中要用到整型、浮点型和字符串这三种数据类型时相对比较简单,只需要知道如何生成和维护它们就可以了。下面的例子给出了如何在C语言中使用Python的这三种数据类型:
例2:typeifs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// build an integer PyObject* pInt = Py_BuildValue( "i" , 2003); assert (PyInt_Check(pInt)); int i = PyInt_AsLong(pInt); Py_DECREF(pInt); // build a float PyObject* pFloat = Py_BuildValue( "f" , 3.14f); assert (PyFloat_Check(pFloat)); float f = PyFloat_AsDouble(pFloat); Py_DECREF(pFloat); // build a string PyObject* pString = Py_BuildValue( "s" , "Python" ); assert (PyString_Check(pString); int nLen = PyString_Size(pString); char * s = PyString_AsString(pString); Py_DECREF(pString); |
Python语言中的元组是一个长度固定的数组,当Python解释器调用C语言扩展中的方法时,所有非关键字(non-keyword)参数都以元组方式进行传递。下面的例子示范了如何在C语言中使用Python的元组类型:
例3:typetuple.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// create the tuple PyObject* pTuple = PyTuple_New(3); assert (PyTuple_Check(pTuple)); assert (PyTuple_Size(pTuple) == 3); // set the item PyTuple_SetItem(pTuple, 0, Py_BuildValue( "i" , 2003)); PyTuple_SetItem(pTuple, 1, Py_BuildValue( "f" , 3.14f)); PyTuple_SetItem(pTuple, 2, Py_BuildValue( "s" , "Python" )); // parse tuple items int i; float f; char *s; if (!PyArg_ParseTuple(pTuple, "ifs" , &i, &f, &s)) PyErr_SetString(PyExc_TypeError, "invalid parameter" ); // cleanup Py_DECREF(pTuple); |
Python语言中的列表是一个长度可变的数组,列表比元组更为灵活,使用列表可以对其存储的Python对象进行随机访问。下面的例子示范了如何在C语言中使用Python的列表类型:
例4:typelist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// create the list PyObject* pList = PyList_New(3); // new reference assert (PyList_Check(pList)); // set some initial values for ( int i = 0; i < 3; ++i) PyList_SetItem(pList, i, Py_BuildValue( "i" , i)); // insert an item PyList_Insert(pList, 2, Py_BuildValue( "s" , "inserted" )); // append an item PyList_Append(pList, Py_BuildValue( "s" , "appended" )); // sort the list PyList_Sort(pList); // reverse the list PyList_Reverse(pList); // fetch and manipulate a list slice PyObject* pSlice = PyList_GetSlice(pList, 2, 4); // new reference for ( int j = 0; j < PyList_Size(pSlice); ++j) { PyObject *pValue = PyList_GetItem(pList, j); assert (pValue); } Py_DECREF(pSlice); // cleanup Py_DECREF(pList); |
Python语言中的字典是一个根据关键字进行访问的数据类型。下面的例子示范了如何在C语言中使用Python的字典类型:
例5:typedic.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// create the dictionary PyObject* pDict = PyDict_New(); // new reference assert (PyDict_Check(pDict)); // add a few named values PyDict_SetItemString(pDict, "first" , Py_BuildValue( "i" , 2003)); PyDict_SetItemString(pDict, "second" , Py_BuildValue( "f" , 3.14f)); // enumerate all named values PyObject* pKeys = PyDict_Keys(); // new reference for ( int i = 0; i < PyList_Size(pKeys); ++i) { PyObject *pKey = PyList_GetItem(pKeys, i); PyObject *pValue = PyDict_GetItem(pDict, pKey); assert (pValue); } Py_DECREF(pKeys); // remove a named value PyDict_DelItemString(pDict, "second" ); // cleanup Py_DECREF(pDict); |
7、数据转换,在c/c++与python交互时,都是通过PyObject来传 入和传出数据的,Python提供相关函数对PyObject数据进行转换,转换时使用格式字符串来控制生成的对象类型,具体可参见 https://docs.python.org/3.5/c-api/arg.html官方文档:
A) 将c/c++数据转换成PyObject:
PyObject *pInt=Py_BuildValue("i",2003);
PyObject *pStr=Py_BuildValue("s","This is a string");
PyObject *pTuples=Py_BuildValue("()"); //生成空元组,可作为调用不包含任何参数的函数时,传递空参数
PyObject *pTuples=Py_BuildValue("(s)","This is a string"); //生成一个元素的元组,可作为调用只包含一个字符参数的函数时,传递一个字符参数
B) 将PyObject数据转换成c/c++数据:
1) int bb=0; PyArg_Parse(pObjcet,"i",&bb); //这里pObject是包含整数数据的Python对象,第二个字符串参数"i"指定转换类型,第三个参数将结果值存入bb变量;
2) char * cc=NULL; PyArg_parse(pObject,"s",&cc); //这是字符串转换
3) char * cc=NULL; PyArg_parse(pObject,"(s)",&cc); //这是包含一个字符串元素元组转换
8、调用Python模块函数时,传入参数时,要构造一个参数元组,如:presult = PyObject_CallObject(pfunction, args);这里args就是一个元组,作为被调用函数的参数列表;
A、如参数为空,则这样构造:args=Py_BuildValues("(si)","abc",10); 表示构造二个参数的元组,一个是字符型,另一个是整;多个参数,可参照处;
B、如果参数为空,则需构造一个包含0个元素元组:args=Py_BuildValues("()");
注意以上二种都在格式字符串中包含"()",这是指示构造元;作为函数调用参数必须传递元组,也必须这样构;
下例是通过可变参数来构造调用函数参数元组:
int PythonHandler::PyModuleRunFunction(const char *module, const char *function,
const char *result_format, void *result, const char *args_format, ...)
{
......
//这里构造调用函数所使用的参数元组
va_list args_list;
va_start(args_list, args_format);
args = Py_VaBuildValue(const_cast<char *>(args_format), args_list);
va_end(args_list);
...
if (!args)
{
//args为空,则元组构造失败
Py_DECREF(pfunction);
return -3;
}
...
presult = PyObject_CallObject(pfunction,args); //调用函数
PS:我只把暂时用得到的拿过来了,还有很多有用的可以查看转自的网站,想了解更多查看python官网
https://docs.python.org/2/c-api/object.html