simondss 2023-02-16 09:42 采纳率: 100%
浏览 16
已结题

C程序 struct问题以及注册问题

在GIT上查找到一个DOIP的工程,查看代码时,发现几个问题,希望各位协助下。
以下代码属于原工程所有。

struct _proto_node;
typedef struct _proto_node proto_tree;

这里为什么只是struct _proto_node;
没有定义内容也可以使用么?

另外在本工程中多次出现类似下列的代码,这个是C里面的什么用法?
感觉像是要注册一个列表。请指导。

/* Register DoIP Protocol header */
void register_doip_header(void)
{
    static hf_register_info hf[] = {
        {&hf_doip_version,
         {"Version", "doip.version",
          FT_UINT8, BASE_HEX,
          NULL, 0x0,
          NULL, HFILL}},
        {&hf_doip_inv_version,
         {"Inverse version", "doip.inverse",
          FT_UINT8, BASE_HEX,
          NULL, 0x0,
          NULL, HFILL}},
        {&hf_doip_type,
         {"Type", "doip.type",
          FT_UINT16, BASE_HEX,
          VALS(doip_payloads), 0x0,
          NULL, HFILL}},
        {&hf_doip_length,
         {"Length", "doip.length",
          FT_UINT32, BASE_DEC,
          NULL, 0x0,
          NULL, HFILL}}};

    proto_register_field_array(proto_doip, hf, array_length(hf));
}

感谢!

  • 写回答

4条回答 默认 最新

  • 量化研究所 2023-02-16 09:51
    关注

    关于结构体的定义
    在这段代码中,struct _proto_node 只是一个结构体声明,其目的是告诉编译器有一个叫做 _proto_node 的结构体类型,但是并没有给出具体的结构体定义。这是 C 语言中常用的一种声明方式,叫做“不完整类型”(Incomplete Type),它只声明了类型的名称而没有给出具体的定义,主要用于在某些情况下先声明类型,后面再定义具体的结构体。

    在这里,typedef struct _proto_node proto_tree; 则将 _proto_node 定义为 proto_tree 的别名,即 proto_tree 等同于 _proto_node。

    关于注册列表
    这段代码是在 Wireshark 网络协议分析工具中用来注册协议解析器的代码。在 Wireshark 中,每个协议都需要进行解析以便对网络数据进行分析。这段代码的作用是注册一个叫做 proto_doip 的协议解析器,并向其添加一些字段(field)。

    在代码中,hf_register_info 结构体表示一个协议字段,它包含了字段的名字、标识符、数据类型、值域等信息。在 register_doip_header 函数中,定义了一个静态的 hf 数组,用于存放这个协议解析器的所有字段信息。然后,调用 proto_register_field_array 函数,将这些字段信息注册到 proto_doip 协议解析器中。

    通过这种方式,Wireshark 就可以根据注册的协议解析器和字段信息,对网络数据进行解析和显示。
    关于结构体的定义

    struct _proto_node;
    typedef struct _proto_node proto_tree;
    

    这里的代码定义了一个结构体 _proto_node,但是并没有给出具体的结构体定义。然后通过 typedef 关键字将 _proto_node 定义为 proto_tree 的别名,即 proto_tree 等同于 _proto_node。在代码中使用 proto_tree 作为结构体类型时,编译器会知道它实际上是 _proto_node 类型。

    关于注册列表

    
    typedef struct _hf_register_info {
        /* 字段名 */
        char* name;
        /* 字段标识符 */
        char* abbrev;
        /* 字段数据类型 */
        int type;
        /* 字段数值 */
        int display;
        /* 字段值域 */
        void* vals;
        /* 保留字段 */
        guint32 bitmask;
        /* 字段说明 */
        char* blurb;
    } hf_register_info;
    
    /* 注册 DoIP 协议头 */
    void register_doip_header() {
        /* 定义协议字段 */
        static hf_register_info hf[] = {
            { &hf_doip_version, { "Version", "doip.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
            { &hf_doip_inv_version, { "Inverse version", "doip.inverse", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
            { &hf_doip_type, { "Type", "doip.type", FT_UINT16, BASE_HEX, VALS(doip_payloads), 0x0, NULL, HFILL } },
            { &hf_doip_length, { "Length", "doip.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }
        };
    
        /* 将协议字段注册到协议解析器中 */
        proto_register_field_array(proto_doip, hf, array_length(hf));
    }
    
    

    这里定义了一个 hf_register_info 结构体,表示一个协议字段。在 register_doip_header 函数中,定义了一个静态的 hf 数组,用于存放 proto_doip 协议解析器的所有字段信息。然后,调用 proto_register_field_array 函数,将这些字段信息注册到 proto_doip 协议解析器中。在代码中使用 VALS(doip_payloads) 时,它表示一个指向名为 doip_payloads 的值域数组的指针,用于指定字段的值域。

    望采纳。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月24日
  • 已采纳回答 2月16日
  • 创建了问题 2月16日

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看