• 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     // 初始化Python
    11     Py_Initialize();
    12     // 检查初始化是否成功
    13     if (!Py_IsInitialized()) {
    14         return -1;
    15     }
    16     // 添加当前路径
    17     //把输入的字符串作为Python代码直接运行,返回0
    18     //表示成功,-1表示有错。大多时候错误都是因为字符串中有语法错误。
    19     PyRun_SimpleString("import sys");
    20     int result = PyRun_SimpleString("print('----------import sys-------')");
    21     if (result!=-1){
    22         printf("test pyhon OK!
    
    ");
    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 并执行test
    43     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("
    -----------c++层接收py返回:buf1:%d,buf2:%d,buf3:%s,buf4:%d
    ", 
    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     // 关闭Python
    92     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] + 1
    12     buf2 = ret[1] + 1
    13     buf4 = ret[3] + 1
    14     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, 'kjacx00xfexfexfexfexfexfe', 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++之间的框架消息及测试代码的构造

  • 相关阅读:
    20220530 08:00:01
    操作系统:Linux如何获取所有设备信息
    操作系统:设备I/O 如何在内核中注册设备?
    操作系统:设备I/O 设备如何处理内核I/O包
    Selenium(七)分布式
    软件风险分为内部风险和外部风险
    关联用户属性标签表和用户行为权重表
    场景法
    统计品牌销量top10
    《Android 编程权威指南》学习笔记 : 第11章 数据库与 Room 库
  • 原文地址:https://www.cnblogs.com/left69/p/7216946.html
Copyright © 2020-2023  润新知