c调用python记录
C调用python的实例。
1. 应用场景
c代码中需要数据库的支持,但是引入数据库十分的复杂且麻烦,所以考虑用python读取配置文件,然后将数据返回到C。
2.调用步骤
a, 添加必要的宏和python路径
#define MS_NO_COREDLL #include "C:\Python27\include\python.h" #pragma comment(lib, "C:\\Python27\\libs\\python27.lib")
b,初始化python解释器
Py_Initialize(); if ( !Py_IsInitialized() ) { printf( "Cannot initialize python27.\n" ); return -1; }
c,将python文件的字符串转换为python字符,并导入python文件。
/*Create python string symbol, s stand for string and pytest stand for pytest.py*/ pName = Py_BuildValue( "s", "pytest" ); /*Import the python file.*/ pModule = PyImport_Import( pName ); if ( !pModule ) { printf("Couldnot find pytest.py .\n"); return -1; }
d,导入python文件中的处理函数
pDict = PyModule_GetDict( pModule ); if ( !pDict ) { return -1; } pFunc = PyDict_GetItemString( pDict, functionName ); if ( !PyCallable_Check( pFunc ) ) { printf("Couldnot find function.\n" ); return -1; }
e,传入参数,入参类型为tuple.PyTuple_New( 1 )产生一个tuple,有1个元素。Py_BuildValue( "i", 1 )将数字1转换为python的整形类型。PyObject_CallObject()调用执行函数执行。
pArgs = PyTuple_New( 1 ); PyTuple_SetItem( pArgs, 0, Py_BuildValue( "i", 1 ) ); pRetVal = PyObject_CallObject( pFunc, pArgs );
f,Py_DECREF清除并释放资源。
g,Py_Finalize()释放python状态机。
完整的代码如下,需要在同目录下创建test.txt文件,保证数据的存在。
textCPython.c
#include <stdio.h> #include <stdlib.h> #define MS_NO_COREDLL #include "C:\Python27\include\python.h" #pragma comment(lib, "C:\\Python27\\libs\\python27.lib") int ReadFile() { PyObject* pName; PyObject* pModule = NULL; PyObject* pDict = NULL; PyObject* pFunc = NULL; PyObject* pArgs = NULL; PyObject* pRetVal = NULL; PyObject* pList = NULL; int i = 0; Py_ssize_t num = 0; char* functionName = "GetFileContent"; Py_Initialize(); if ( !Py_IsInitialized() ) { printf( "Cannot initialize python27.\n" ); return -1; } /*Create python string symbol, s stand for string and pytest stand for pytest.py*/ pName = Py_BuildValue( "s", "pytest" ); /*Import the python file.*/ pModule = PyImport_Import( pName ); if ( !pModule ) { printf("Couldnot find pytest.py .\n"); return -1; } pDict = PyModule_GetDict( pModule ); if ( !pDict ) { return -1; } pFunc = PyDict_GetItemString( pDict, functionName ); if ( !PyCallable_Check( pFunc ) ) { printf("Couldnot find function.\n" ); return -1; } pArgs = PyTuple_New( 1 ); PyTuple_SetItem( pArgs, 0, Py_BuildValue( "i", 1 ) ); pRetVal = PyObject_CallObject( pFunc, pArgs ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "tupleno" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "ringprofile" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "id" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "time" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "on1" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "off1" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "on2" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "off2" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "on3" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "off3" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "on4" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "off4" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "on5" ) ) ); printf("%s\n", PyString_AsString( PyDict_GetItemString( pRetVal, "off5" ) ) ); Py_DECREF( pName ); Py_DECREF( pDict ); Py_DECREF( pArgs ); Py_DECREF( pModule ); Py_Finalize(); return 1; } int main() { if ( -1 == ReadFile() ) { return -1; } return 0; }
pytest.py
import os def GetListFromLine( str ): itemList = [ li.replace( ' ', '' ) for li in str.split( ':' ) ] return [ li.replace( '\n', '' ) for li in itemList ] def GetFileContent( id ): f = open( 'test.txt' ) try: retVal = [] for line in f.readlines(): if line != '\n': retVal.append( GetListFromLine( line ) ) return dict( retVal ) finally: f.close()
test.txt
tupleno: 1 ringprofile : 1 id : 0 time : 12000 on1 : 100 off1 : 400 on2 : 0 off2 : 0 on3 : 0 off3 : 0 on4: 0 off4 : 0 on5 : 0 off5 : 0