我的python版本是3.7.3
C代码如下:
/**************************************************************************************************************************************************
* describe :c调用pyhton的AddMult函数,对两个数进行相加,相乘,输出结果对(sum,multiply)
*
* author :chansy@20210421
* input :a 输入变量,b输入变量
* return :无
**************************************************************************************************************************************************/
void call_python_AddMult(int a,int b)
{
PyObject * pModule=NULL;
PyObject * pFunc=NULL;
PyObject* pArgs = NULL;
PyObject* pRet = NULL;
Py_Initialize();//主要是初始化python解释器。
PyRun_SimpleString("import sys");//相当于在python中的import sys语句。
PyRun_SimpleString("from ctypes import *");
PyRun_SimpleString("import struct");
PyRun_SimpleString("sys.path.append('/userdata')");//是将搜索路径设置为userdata目录。
pArgs = Py_BuildValue("ii", a, b);
pModule = PyImport_ImportModule("c_call_python");//是利用导入文件函数将c_call_python.py函数导入
if (NULL == pModule)
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"PyImport_ImportModule get NULL\n");
Py_Finalize();
return;
}
pFunc = PyObject_GetAttrString(pModule,"AddMult");//查找AddMult
if (!pFunc || !PyCallable_Check(pFunc))
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"can't findfunction [AddMult]\n");
}
else
{
int sum=0,multiply=0,parseRet=0;
pRet=PyEval_CallObject(pFunc,pArgs);//调用AddMult
parseRet=PyArg_Parse(pRet, "(ii)", &sum,&multiply);
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"parseRet=%d,sum:%d,multiply:%d\n",parseRet,sum,multiply);
}
Py_Finalize();
}
/**************************************************************************************************************************************************
* describe :c调用pyhton的ArrParse函数,打印输入的字符串
*
* author :chansy@20210421
* input :无
* return :无
**************************************************************************************************************************************************/
void call_python_ArrParse()
{
PyObject * pModule=NULL;
PyObject * pFunc=NULL;
PyObject* pArgs = NULL;
PyObject* pRet = NULL;
Py_Initialize();//主要是初始化python解释器。
PyRun_SimpleString("import sys");//相当于在python中的import sys语句。
PyRun_SimpleString("from ctypes import *");
PyRun_SimpleString("import struct");
PyRun_SimpleString("sys.path.append('/userdata')");//是将搜索路径设置为userdata目录。
pModule = PyImport_ImportModule("c_call_python");//是利用导入文件函数将c_call_python.py函数导入
if (NULL == pModule)
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"PyImport_ImportModule get NULL\n");
Py_Finalize();
return;
}
PyObject *pArgsNew = PyTuple_New(1);
pFunc = PyObject_GetAttrString(pModule,"ArrParse");//查找ArrParse
char * iStr = " array";
PyTuple_SetItem(pArgsNew, 0, Py_BuildValue("s", iStr));
if (!pFunc || !PyCallable_Check(pFunc))
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"can't findfunction [ArrParse]\n");
}
else
{
pRet=PyEval_CallObject(pFunc,pArgsNew);//调用
if (NULL == pRet)
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"pRet=NULL\n");
else
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"pRet not NULL\n");
}
Py_Finalize();
}
/**************************************************************************************************************************************************
* describe :c调用pyhton的hex_arr_fun函数,打印输入的十六进制数组第一个字节
*
* author :chansy@20210421
* input :无
* return :无
**************************************************************************************************************************************************/
void call_python_hex_arr_fun()
{
PyObject * pModule=NULL;
PyObject * pFunc=NULL;
PyObject* pArgs = NULL;
PyObject* pRet = NULL;
Py_Initialize();//主要是初始化python解释器。
PyRun_SimpleString("import sys");//相当于在python中的import sys语句。
PyRun_SimpleString("from ctypes import *");
PyRun_SimpleString("import struct");
PyRun_SimpleString("sys.path.append('/userdata')");//是将搜索路径设置为userdata目录。
pModule = PyImport_ImportModule("c_call_python");//是利用导入文件函数将c_call_python.py函数导入
if (NULL == pModule)
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"PyImport_ImportModule get NULL\n");
Py_Finalize();
return;
}
PyObject *pArgsHexArr = PyTuple_New(1);
pFunc = PyObject_GetAttrString(pModule,"hex_arr_fun");//查找ArrParse
char hexarr[12]={0x55,0x20,0x10,0x10,0x10,0x20,0x10,0x10,'A'};
PyTuple_SetItem(pArgsHexArr, 0, Py_BuildValue("s", hexarr));
if (!pFunc || !PyCallable_Check(pFunc))
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"can't findfunction [print_hex]\n");
}
else
{
pRet=PyEval_CallObject(pFunc,pArgsHexArr);//调用模块
if (NULL == pRet)
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"pRet=NULL\n");
else
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"pRet not NULL\n");
}
Py_Finalize();
}
/**************************************************************************************************************************************************
* describe :c调用pyhton的int_arr_fun函数,打印输入的int数组
*
* author :chansy@20210421
* input :无
* return :无
**************************************************************************************************************************************************/
void call_python_int_arr_fun()
{
int array[]={100,123,456,789};
int size = sizeof(array)/sizeof(int);
int retval=0;
PyObject * pModule=NULL;
PyObject * pFunc=NULL;
PyObject* pArgs = NULL;
PyObject* pRet = NULL;
Py_Initialize();//主要是初始化python解释器。
PyRun_SimpleString("import sys");//相当于在python中的import sys语句。
PyRun_SimpleString("from ctypes import *");
PyRun_SimpleString("import struct");
PyRun_SimpleString("sys.path.append('/userdata')");//是将搜索路径设置为userdata目录。
pModule = PyImport_ImportModule("c_call_python");//是利用导入文件函数将c_call_python.py函数导入
if (NULL == pModule)
{
jprint(MOD_JPRINT_MAIN,MOD_DEBUG_TRACE,"PyImport_ImportModule get NULL\n");
Py_Finalize();
return;
}
PyObject *pArgslist = PyTuple_New(1);
pFunc = PyObject_GetAttrString(pModule, "int_arr_fun");
PyObject *mylist = PyList_New(size);
for (size_t i = 0; i != size; ++i) {
PyList_SET_ITEM(mylist, i,Py_BuildValue("i", array[i]));//PyInt_FromLong(array[i])
}
PyTuple_SetItem(pArgslist, 0, mylist);
if (!pFunc || !PyCallable_Check(pFunc))
{
printf("int_arr_fun can't call,%d\n",pFunc);
}
else
{
pRet = PyEval_CallObject(pFunc, pArgslist);
printf("after call object\n");
}
Py_Finalize();//清理python环境释放资源
}
typedef struct header_ {
int buf1;
int buf2;
char buf3[12];
int buf4;
}header;
void call_python_testStruct()
{
// 初始化Python
Py_Initialize();
PyRun_SimpleString("import sys");//相当于在python中的import sys语句。
PyRun_SimpleString("from ctypes import *");
PyRun_SimpleString("import struct");
PyRun_SimpleString("sys.path.append('/userdata')");//是将搜索路径设置为userdata目录。
//PyObject *pName = PyBytes_FromString("Test001");PyObject *pModule = PyImport_Import(pName); //调用Python的Module的另一种方法
PyObject * pModule = NULL;
PyObject *pDict = NULL;
PyObject * pFunc = NULL;
pModule = PyImport_ImportModule("c_call_python");
if (!pModule) {
printf("can't find c_call_python.py\n");
return ;
}
pDict = PyModule_GetDict(pModule);
if (!pDict) return ;
//下面这段是查找函数testStruct并执行testStruct
pFunc = PyDict_GetItemString(pDict, "testStruct");
if (!pFunc || !PyCallable_Check(pFunc)) {
printf("can't find function [testStruct]\n");
return ;
}
//创建结构体
header input;
memset(&input,0,sizeof(input));
input.buf1 = 1;
input.buf2 = 2;
input.buf4 = 3;
//strcpy(input.buf3, "kjaf");
//打包成string
char * byInput = new char(sizeof(input));
if (NULL == byInput)
{
printf("no enough mem\n");
return ;
}
memcpy(byInput, &input, sizeof(input));
//申请python入参
PyObject *pArgs = PyTuple_New(1);
//对python入参进行赋值; s代表char*格式, #代表传入指定长度
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s#",byInput , sizeof(input)));
//PyObject *Pystructs = Py_BuildValue("s#",byInput, sizeof(input));//为了检验入参是否为空
//if (Pystructs == nullptr){printf("Pystructs is nullptr"); }
//执行函数
PyObject *pResult = PyObject_CallObject(pFunc, pArgs);
if (NULL == pResult)
{
printf("get pResult == NULL\r\n");
}
else
{
printf("get pResult not NULL\r\n");
}
header rspbuf;
memset(&rspbuf,0,sizeof(header));
char* pRsp=PyBytes_AS_STRING(pResult);//这里使用PyArg_Parse(pResult, "s#", &pRsp);会报段错误
printf("pRsp==");
for (int i = 0; i<sizeof(header);i++)
{
printf("0x%x ",pRsp[i]);
}
printf("\n");
if (NULL != pRsp)
{
header* pstRsp = (header*)pRsp;//把string转化为结构体
printf("\n-----------c++层接收py返回:\nbuf1:%d , buf2:%d , buf4:%d\n\n",
pstRsp->buf1, pstRsp->buf2, pstRsp->buf4);
}
else
{
printf("pRsp is NULL\n");
}
Py_Finalize();
delete byInput;
}
python代码如下
def AddMult(a, b):
"""
"""
print("in FunctionAddMult...")
print(a)
print(b)
return a + b, a * b
def ArrParse(iArr):
"""
"""
print(iArr)
def print_hex(bytes):
l = [hex(int(i)) for i in bytes]
print(" ".join(l))
def print_string_to_hex(str):
mybytes=bytes.fromhex(mystr)
print_hex(mybytes)
def hex_arr_fun(hexstr):
print(hexstr)
mystr = hexstr.encode()
bin_buf3 = struct.pack('11s', mystr)
print(bin_buf3[0])
def int_arr_fun(intarr):
"""
"""
print(intarr)
def testStruct(a):
"""
"""
#a = a.encode('utf-8')#要注意把从C传过来的string转化为bytes,以便struct.unpack解析
ret = struct.unpack('i i 12s i', a)
print("--------------------python receive c++ struct:\n")
#print(ret)
buf1 = ret[0] + 1
buf2 = ret[1] + 1
buf4 = ret[3] + 1
print("--------------------begin pack data and begin send to c++\n")
bin_buf_all = struct.pack('ii12si', buf1, buf2,b"dfds", buf4)
print("bin_buf_all:")
print(bin_buf_all)
print("----------------------------python end-----------------------")
return bin_buf_all
附转换表
参考博文
https://blog.csdn.net/qq_31342997/article/details/88368420
在我的环境里,使用以上博文的代码,在调用PyArg_Parse(pResult, "s#", &pRsp);时,会报段错误。