如何用go语言来转换c语言的结构体到go的结构体

byteman_Go · 2017-01-11 04:57:24 · 3839 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-01-11 04:57:24 的主题,其中的信息可能已经有所发展或是发生改变。

在和c和c++客户端做网络通信的时候,为了方便,经常以结构体作为通信的参数 我们需要将c中的结构体直接转换到go中的结构体中。

在c语言中的结构体实例如下

注意要以1字节对齐。

#pragma pack(push) // 将当前pack设置压栈保存
#pragma pack(1)// 必须在结构体定义之前使用

typedef struct
{
    unsigned short dev_id;
    unsigned char  dir;
    unsigned char  cmd;
    unsigned char  oper;
    unsigned short len;
}Msg_Head;



typedef struct {
        double             Longitude;    // 经度
        double             Latitude;    // 纬度
        unsigned char     ns;            // 南北值为,'n'或's'
        unsigned char     ew;            // 东西,'e'或'w'
}GpsDef;


typedef struct {
        unsigned char     year;        // 当前年减去2000,如2016年,year实际保存16。
        unsigned char    month;
        unsigned char    day;
        unsigned char    hour;
        unsigned char    min;
        unsigned char    sec;
}DateDef;

#define        LICENSE_LEN        10
#define        DUTY_LEN        16

typedef struct {
        int     wet;                        // 总重量
        char     license_plate[LICENSE_LEN];    // 车辆号牌信息(或本机信息)、
        GpsDef     gps;                        // GPS信息、
        DateDef    up_date;                    // 发送的实时日期时间.
}WeightMsg;

#pragma pack(pop)


//go语言中的结构体

type GpsDef struct {
    Longitude float64 // 经度
    Latitude  float64 // 纬度
    Ns        uint8   // 南北值为,'n'或's'
    Ew        uint8   // 东西,'e'或'w'
}

type DateDef struct {
    Year  uint8 // 当前年减去2000,如2016年,year实际保存16。
    Month uint8
    Day   uint8
    Hour  uint8
    Min   uint8
    Sec   uint8
}

const (
    LICENSE_LEN = 10
    DUTY_LEN    = 16
)

//总重量消息
type WeightMsg struct {
    Wet    int32             // 重量、
    Plate  [LICENSE_LEN]byte // 车辆号牌信息
    Gps    GpsDef            // GPS信息、
    UpDate DateDef           // 发送的实时日期时间.
}

我们再go中收到的数据是byte slice,我们需要将slice直接转换为go中对应的结构体

func unSerial(data []byte, n uint16, msg interface{}) bool {

    r := bytes.NewReader(data[:n])
    err := binary.Read(r, binary.LittleEndian, msg)
    if err != nil {
        fmt.Println(err)
        return false
    }
    fmt.Print("%v", msg)
    return true
}


w := &WeightMsg{}

if unSerial(d, n, w) {
    //这里的w就是转换后的数据了
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3839 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传