首页 > 代码库 > c++调用python系列(1): 结构体作为入参及返回结构体

c++调用python系列(1): 结构体作为入参及返回结构体

 

最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试;

因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给游戏服务器,响应消息再交由python进行校验;

技术分享

 

开始:

首先是c++调用python这一层需要打通;

幸运的是python自己有一套库提供c/c++进行调用;

下面我贴代码;用的vs2013,python用的2.7

 1 // python_c++.cpp : 定义控制台应用程序的入口点。 2 // 3  4 #include "stdafx.h" 5 #include <Python.h> 6 #pragma comment(lib, "Ws2_32.lib") 7  8 int _tmain(int argc, _TCHAR* argv[]) 9 {10     // 初始化Python11     Py_Initialize();12     // 检查初始化是否成功13     if (!Py_IsInitialized()) {14         return -1;15     }16     // 添加当前路径17     //把输入的字符串作为Python代码直接运行,返回018     //表示成功,-1表示有错。大多时候错误都是因为字符串中有语法错误。19     PyRun_SimpleString("import sys");20     int result = PyRun_SimpleString("print(‘----------import sys-------‘)");21     if (result!=-1){22         printf("test pyhon OK!\n\n");23     }24     25     PyRun_SimpleString("sys.path.append(‘./‘)");26 27     // 载入名为pytest的脚本28     PyObject *pName = PyBytes_FromString("pytest");29     PyObject *pModule = PyImport_Import(pName);30     if (!pModule) {31         printf("can‘t find pytest.py");32         getchar();33         return -1;34     }35 36     PyObject *pDict = PyModule_GetDict(pModule);37     if (!pDict) {38         getchar();39         return -1;40     }41 42     //下面这段是查找函数test 并执行test43     PyObject *pFunc = PyDict_GetItemString(pDict, "test2");44     if (!pFunc || !PyCallable_Check(pFunc)) {45         printf("can‘t find function [test2]");46         getchar();47         return -1;48     }49 50     typedef struct header_ {51         int buf1;52         int buf2;53         char buf3[11];54         int buf4;55     }header;56 57     //创建结构体58     header input;59     memset(&input,0,sizeof(input));60     input.buf1 = 1;61     input.buf2 = 2;62     input.buf4 = 3;63     strcpy_s(input.buf3, "kjac");64     65     //打包成byte*66     char * byInput = new char(sizeof(input));67     memcpy(byInput, &input, sizeof(input));68 69     //申请python入参70     PyObject *pArgs = PyTuple_New(1);71     //对python入参进行赋值; s代表char*格式, #代表传入指定长度72     PyTuple_SetItem(pArgs, 0, Py_BuildValue("s#", byInput, sizeof(input)));73 74     //执行函数75     PyObject *pResult = PyObject_CallObject(pFunc, pArgs);76 77     char* pRsp;78     //获取返回值79     PyArg_Parse(pResult, "s", &pRsp);80 81     //转成结构体82     header* pstRsp = (header*)pRsp;83     printf("\n-----------c++层接收py返回:buf1:%d,buf2:%d,buf3:%s,buf4:%d\n", 84     pstRsp->buf1, pstRsp->buf2, pstRsp->buf3, pstRsp->buf4);85 86     //释放87     Py_DECREF(pName);88     Py_DECREF(pArgs);89     Py_DECREF(pModule);90 91     // 关闭Python92     Py_Finalize();93     getchar();94     return 0;95 }

 

下面的是python代码

 1 import struct 2  3 def test(a): 4     print("----------------------------python 1-----------------------") 5     ret = struct.unpack(ii11si, a) 6     print("----------------------------python deal-----------------------") 7     print("--------------------python receive c++ struct:") 8     print("begin unpack:") 9     print("")10     print(ret)11     buf1 = ret[0] + 112     buf2 = ret[1] + 113     buf4 = ret[3] + 114     print("--------------------begin pack data and begin send to c++")15     print("")16     bin_buf_all = struct.pack(ii11si, buf1, buf2, "dfds", buf4)17     print("----------------------------python end-----------------------")18     return bin_buf_all

 

下面附上vs2013的工程属性修改

技术分享

设置python工程的include路径和libs路径

技术分享

 

技术分享

 

 接下来;就可以编译输出了;

----------import sys-------test pyhon OK!----------------------------python 1---------------------------------------------------python deal-------------------------------------------python receive c++ struct:begin unpack:(1, 2, ‘kjac\x00\xfe\xfe\xfe\xfe\xfe\xfe‘, 3)--------------------begin pack data and begin send to c++----------------------------python end----------------------------------c++层接收py返回:buf1:2,buf2:3,buf3:dfds,buf4:4

 技术分享

 

 

现在c++调用python已经大功告成了;下面就是python和c++之间的框架消息及测试代码的构造

 

 

 

技术分享

c++调用python系列(1): 结构体作为入参及返回结构体