不枉初心,砥砺前行

皮皮祥的博客

欢迎留言,评论

导航

C++:将char*指针强制转换成一个指向结构体的指针

在使用Socket与雷达进行通信采集数据时,会遇到“打包与解包”的问题,在打包和解包过程中,会涉及到结构体指针与字符指针间的强制转换。如下:

打包就是将包头与信息封装成一定大小的包,作为发送单元进行发送。

1、首先将雷达数据格式进行打包:(把数据格式打包成一种结构体数据类型)

  1.  
    typedef struct _tag_OLE2D_Block
  2.  
    {
  3.  
    DWORD Header;//标识符//typedef unsigned long DWORD;
  4.  
    WORD ProtocolVersion;//协议版本WORD类型实际上就是一个无符号的短整型
  5.  
    BYTE Ratio; //距离比例
  6.  
    CHAR Manufactor[3];//品牌商代码
  7.  
    CHAR Model[12];//销售型号字符串
  8.  
    WORD ModelID;//内部型号代码
  9.  
    WORD HardwareVersion;//硬件版本
  10.  
    WORD SoftwareVersion;//软件版本
  11.  
    DWORD Timestamp;//时间戳(ms)
  12.  
    WORD Rotate;//转速
  13.  
    BYTE SafeStatus;//安全区域
  14.  
    BYTE ErrorStatus;//错误状态
  15.  
    DWORD Reserved[1];//保留
  16.  
    struct Point2D//结构里边有一个成员是结构
  17.  
    {
  18.  
    WORD Angle;
  19.  
    WORD Distance;
  20.  
    WORD Intensity;
  21.  
    WORD Reversed;
  22.  
    }Points[150];//11111111111111111111111111111111111111111111结构要扩展
  23.  
    }OLE2D_Block;//是一个数据结构(雷达反馈数据的数据结构,OLE2D_Block结构体的实例)

定义好包头后,还需要编写打包程序,此时就涉及到char*指针强制转换成一个指向结构体的指针。

char*指针强制转换成一个指向结构体的指针的可行性:指针其实就是一个地址, 指向一段内存, 至于怎么解释这段内存就得看这个指针是什么类型,内容是以字符串传输的,现在想以结构体解析出来,这样是可以的。

比如:

  1.  
    char pBuf[65536]//定义字符数据接收通信传输数据
  2.  
     
  3.  
    ...
  4.  
     
  5.  
    proceedata(char* recv)//其中参数char* recv是定义字符指针,来作为数据处理这个函数所要处理的数据
  6.  
    //而我们将数据结构做以打包,所以使用socket通信获取的数据是字符串的形式,故需要将字符串也就是字符数组形式的数据转化为结构体指针的形式
  7.  
    {
  8.  
     
  9.  
    .....
  10.  
    OLE2D_Block* pBlock = (OLE2D_Block*)recv//这里就是将传参进来的recv字符指针强制转化为结构体指针
  11.  
    }

案例演示:

  1.  
    #include <iostream>
  2.  
    #include<stdlib.h>
  3.  
    #include<stdio.h>
  4.  
     
  5.  
    using namespace std;
  6.  
    typedef struct test
  7.  
    {
  8.  
    int a;
  9.  
    double b;
  10.  
    char c;
  11.  
    string str;
  12.  
    };//定义一个测试结构体
  13.  
     
  14.  
    int main(int argc, char* argv[])
  15.  
    {
  16.  
    char* pData = NULL;
  17.  
    pData = new char[100]; //申请一个字符串缓存区,用于存放发送(或接收)的包数据
  18.  
    memset(pData, 0, 100);
  19.  
     
  20.  
    test* a = (test*)pData;//定义一个结构体指针,并把char*缓存区强制转换成结构体指针
  21.  
    a->a = 1;//可以对缓存区进行赋值,这可以理解为包头信息写入到缓存区
  22.  
    a->b = 2.0;
  23.  
    a->c = 'c';
  24.  
    a->str = "abcd";
  25.  
     
  26.  
    cout << "a的地址:" << a << endl;//查看缓存区的值
  27.  
    cout << "a->a:" << a->a << endl;
  28.  
    cout << "a->b:" << a->b << endl;
  29.  
    cout << "a->c:" << a->c << endl;
  30.  
    cout << "a->str:" << a->str << endl;
  31.  
    cout << endl;
  32.  
     
  33.  
    test* b = (test*)pData;//定义一个结构体指针,并把char*缓存区强制转换成结构体指针
  34.  
     
  35.  
    b->a =3;//可以对缓存区进行赋值,这可以理解为包头信息写入到缓存区
  36.  
    b->b = 4.0;
  37.  
    b->c = 'd';
  38.  
    b->str = "efgh";
  39.  
     
  40.  
    cout << "b的地址:" << b << endl;//直接输出缓存区的数据,相当于从接收缓存区将包头信息提取的过程
  41.  
    cout << "b->a:" << b->a << endl;
  42.  
    cout << "b->b:" << b->b << endl;
  43.  
    cout << "b->c:" << b->c << endl;
  44.  
    cout << "b->str:" << b->str << endl;
  45.  
    cout << endl;
  46.  
     
  47.  
    cout << "a的地址:" << a << endl;//查看缓存区的值
  48.  
    cout << "a->a:" << a->a << endl;
  49.  
    cout << "a->b:" << a->b << endl;
  50.  
    cout << "a->c:" << a->c << endl;
  51.  
    cout << "a->str:" << a->str << endl;
  52.  
    cout << endl;
  53.  
     
  54.  
    return 0;
  55.  
    }

结果如下:

打印的地址都一样

PS:

(1)void (*fun)(long* p);//声明函数
     fun dest;//此处fun是一个函数指针,是一个变量,不能用变量定义变量,所以会出错。
(2)typedef void (*fun)(long *p);//此时,fun是一个函数指针类型(因为多了一个typedef)
     fun dest;//用类型定义变量是当然可以的啊

函数指针和指针函数:https://blog.csdn.net/luoyayun361/article/details/80428882?utm_term=%E6%8C%87%E9%92%88%E5%87%BD%E6%95%B0%E5%92%8C%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E6%9C%89%E5%95%A5%E7%94%A8&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-1-80428882&spm=3001.4430

posted on 2022-11-16 23:18  皮皮祥  阅读(1276)  评论(0编辑  收藏  举报