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

6 篇文章 0 订阅

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

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

开始:

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

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

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

// python_c++.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Python.h>
#pragma comment(lib, "Ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    // 初始化Python
    Py_Initialize();
    // 检查初始化是否成功
    if (!Py_IsInitialized()) {
        return -1;
    }
    // 添加当前路径
    //把输入的字符串作为Python代码直接运行,返回0
    //表示成功,-1表示有错。大多时候错误都是因为字符串中有语法错误。
    PyRun_SimpleString("import sys");
    int result = PyRun_SimpleString("print('----------import sys-------')");
    if (result!=-1){
        printf("test pyhon OK!\n\n");
    }

    PyRun_SimpleString("sys.path.append('./')");

    // 载入名为pytest的脚本
    PyObject *pName = PyBytes_FromString("pytest");
    PyObject *pModule = PyImport_Import(pName);
    if (!pModule) {
        printf("can't find pytest.py");
        getchar();
        return -1;
    }

    PyObject *pDict = PyModule_GetDict(pModule);
    if (!pDict) {
        getchar();
        return -1;
    }

    //下面这段是查找函数test 并执行test
    PyObject *pFunc = PyDict_GetItemString(pDict, "test2");
    if (!pFunc || !PyCallable_Check(pFunc)) {
        printf("can't find function [test2]");
        getchar();
        return -1;
    }

    typedef struct header_ {
        int buf1;
        int buf2;
        char buf3[11];
        int buf4;
    }header;

    //创建结构体
    header input;
    memset(&input,0,sizeof(input));
    input.buf1 = 1;
    input.buf2 = 2;
    input.buf4 = 3;
    strcpy_s(input.buf3, "kjac");

    //打包成byte*
    char * byInput = new char(sizeof(input));
    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 *pResult = PyObject_CallObject(pFunc, pArgs);

    char* pRsp;
    //获取返回值
    PyArg_Parse(pResult, "s", &pRsp);

    //转成结构体
    header* pstRsp = (header*)pRsp;
    printf("\n-----------c++层接收py返回:buf1:%d,buf2:%d,buf3:%s,buf4:%d\n",
    pstRsp->buf1, pstRsp->buf2, pstRsp->buf3, pstRsp->buf4);

    //释放
    Py_DECREF(pName);
    Py_DECREF(pArgs);
    Py_DECREF(pModule);

    // 关闭Python
    Py_Finalize();
    getchar();
    return 0;
}

 下面的是python代码

import struct

def test(a):
    print("----------------------------python 1-----------------------")
    ret = struct.unpack('ii11si', a)
    print("----------------------------python deal-----------------------")
    print("--------------------python receive c++ struct:")
    print("begin unpack:")
    print("")
    print(ret)
    buf1 = ret[0] + 1
    buf2 = ret[1] + 1
    buf4 = ret[3] + 1
    print("--------------------begin pack data and begin send to c++")
    print("")
    bin_buf_all = struct.pack('ii11si', buf1, buf2, "dfds", buf4)
    print("----------------------------python end-----------------------")
    return bin_buf_all

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

----------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++之间的框架消息及测试代码的构造

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python调用C++函数并返回结构体,可以通过使用ctypes库来实现。下面是一个示例代码,展示了如何在Python调用一个返回结构体C++函数: 假设我们有一个C++函数,它返回一个结构体类型`MyStruct`: ```c++ #include <iostream> struct MyStruct { int my_int; float my_float; char my_string[256]; }; MyStruct get_struct() { MyStruct s; s.my_int = 123; s.my_float = 3.14; strcpy(s.my_string, "Hello, C++!"); return s; } ``` 现在,我们可以通过使用ctypes库来在Python调用这个函数并获取返回结构体。下面是示例代码: ```python import ctypes # 加载C++编译后的动态链接库 lib = ctypes.cdll.LoadLibrary('./libexample.so') # 定义结构体类型 class MyStruct(ctypes.Structure): _fields_ = [ ("my_int", ctypes.c_int), ("my_float", ctypes.c_float), ("my_string", ctypes.c_char * 256) ] # 设置函数的返回类型为MyStruct类型 lib.get_struct.restype = MyStruct # 调用C++函数并获取返回结构体 result = lib.get_struct() # 输出结构体的成员变量 print(result.my_int) print(result.my_float) print(result.my_string.decode()) ``` 在上面的示例代码中,我们首先使用`cdll.LoadLibrary()`函数加载C++编译后的动态链接库。接着,我们定义了一个结构体类型`MyStruct`,并使用`_fields_`属性来定义结构体的成员变量列表。然后,我们使用`restype`属性将C++函数的返回类型设置为`MyStruct`类型。 最后,我们调用C++函数`get_struct()`并获取返回结构体,将其赋值给变量`result`。我们可以通过访问结构体对象的成员变量来获取它们的值,使用`.decode()`方法将`my_string`成员变量从`bytes`类型转换为字符串类型并输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值