C调用python范例,解决对python返回的字节流的解析

我的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);时,会报段错误。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值