You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传递含联合体的IPv6头结构体作为函数参数时成员无法识别

Linux IPv6驱动中含联合体的结构体成员访问问题

问题描述

在Linux IPv6网络驱动开发中,传递包含联合体的结构体作为函数参数时,函数内部无法识别结构体成员,也无法初始化这些成员。传递无联合体的结构体和函数指针均正常,仅含联合体的结构体成员无法被识别,修正函数参数后问题仍存在。

原代码

#include <stdint.h>

typedef struct In6_addr
{
    union
    {
        uint8_t u6_addr8[16];
        uint16_t u6_addr16[8];
        uint32_t u6_addr32[4];
    } in6_u;
};

typedef struct Ip6_hdr {
    union {
        struct ip6_hdrctl {
            uint32_t ip6_un1_flow;   /* 4 bits version, 8 bits TC, 20 bits flow-ID */
            uint16_t ip6_un1_plen;   /* payload length */
            uint8_t  ip6_un1_nxt;    /* next header */
            uint8_t  ip6_un1_hlim;   /* hop limit */
        } ip6_un1;
        uint8_t ip6_un2_vfc;         /* 4 bits version, top 4 bits tclass */
    } ip6_ctlun;
    struct In6_addr ip6_src;         /* source address */
    struct In6_addr ip6_dst;         /* destination address */
    void (*set6)(struct Ip6_hdr*, union ip6_ctlun*, struct ip6_hdrctl*,  uint32_t , uint16_t, uint8_t, uint8_t, uint8_t, uint16_t,uint32_t, uint8_t, uint16_t, uint32_t);
} __packed;

//corrected Function
void set6(Ip6_hdr* k, ip6_ctlun*, ip6_hdrctl*, uint32_t  ip6_un1_flow, uint16_t ip6_un1_plen, uint8_t  ip6_un1_nxt, uint8_t ip6_un1_hlim, uint8_t ip6_un2_vfc, uint8_t u6_addr8, uint16_t  u6_addr16, uint32_t u6_addr32) {
    k->ip6_un1_flow = ip6_un1_flow;
    k->ip6_un1_plen = ip6_un1_plen;
    k->ip6_un1_nxt = ip6_un1_nxt;
    k->ip6_un1_nxt = ip6_un1_nxt;
}

void constructIphdr6(Ip6_hdr* k) {
    k->ip6_un1_flow = 0;
    k->ip6_un1_plen = 0;
    k->ip6_un1_nxt = 0;
    k->ip6_un1_nxt = 0;
    k->set6 = set6;
}

int main() {
    
    Ip6_hdr k;
    constructIphdr6(&k);
}

错误信息

error: no member named 'ip6_un1_flow' in 'Ip6_hdr'
    k->ip6_un1_flow = ip6_un1_flow;

error: no member named 'ip6_un1_flow' in 'Ip6_hdr'
    k->ip6_un1_flow = 0;

解决方案

问题根源

ip6_un1_flow并非Ip6_hdr的直接成员,它是嵌套在Ip6_hdr的ip6_ctlun联合体中的ip6_un1结构体成员,所有类似的成员访问都缺少了中间层级。此外还存在typedef不完整、函数参数类型未定义的问题。

修正步骤

  1. 补全成员访问路径:访问嵌套成员时必须逐层访问,比如k->ip6_ctlun.ip6_un1.ip6_un1_flow。
  2. 完善typedef定义:给In6_addr的结构体命名,同时给联合体ip6_ctlun和结构体ip6_hdrctl添加typedef,避免函数参数类型未定义。
  3. 修正函数参数:移除无用的参数,让函数逻辑更清晰。

修正后代码

#include <stdint.h>

// 完善In6_addr的typedef定义
typedef struct In6_addr
{
    union
    {
        uint8_t u6_addr8[16];
        uint16_t u6_addr16[8];
        uint32_t u6_addr32[4];
    } in6_u;
} In6_addr;

// 提前typedef嵌套的结构体和联合体
typedef struct ip6_hdrctl {
    uint32_t ip6_un1_flow;   /* 4 bits version, 8 bits TC, 20 bits flow-ID */
    uint16_t ip6_un1_plen;   /* payload length */
    uint8_t  ip6_un1_nxt;    /* next header */
    uint8_t  ip6_un1_hlim;   /* hop limit */
} ip6_hdrctl;

typedef union ip6_ctlun {
    ip6_hdrctl ip6_un1;
    uint8_t ip6_un2_vfc;         /* 4 bits version, top 4 bits tclass */
} ip6_ctlun;

typedef struct Ip6_hdr {
    ip6_ctlun ip6_ctlun;
    In6_addr ip6_src;         /* source address */
    In6_addr ip6_dst;         /* destination address */
    void (*set6)(struct Ip6_hdr*, uint32_t, uint16_t, uint8_t, uint8_t, uint8_t);
} __packed Ip6_hdr;

// 修正函数实现,补全成员访问路径,移除无用参数
void set6(Ip6_hdr* k, uint32_t ip6_un1_flow, uint16_t ip6_un1_plen, uint8_t ip6_un1_nxt, uint8_t ip6_un1_hlim, uint8_t ip6_un2_vfc) {
    k->ip6_ctlun.ip6_un1.ip6_un1_flow = ip6_un1_flow;
    k->ip6_ctlun.ip6_un1.ip6_un1_plen = ip6_un1_plen;
    k->ip6_ctlun.ip6_un1.ip6_un1_nxt = ip6_un1_nxt;
    k->ip6_ctlun.ip6_un1.ip6_un1_hlim = ip6_un1_hlim;
    k->ip6_ctlun.ip6_un2_vfc = ip6_un2_vfc;
}

void constructIphdr6(Ip6_hdr* k) {
    // 补全成员访问路径
    k->ip6_ctlun.ip6_un1.ip6_un1_flow = 0;
    k->ip6_ctlun.ip6_un1.ip6_un1_plen = 0;
    k->ip6_ctlun.ip6_un1.ip6_un1_nxt = 0;
    k->ip6_ctlun.ip6_un1.ip6_un1_hlim = 0;
    k->set6 = set6;
}

int main() {
    Ip6_hdr k;
    constructIphdr6(&k);
    // 示例调用set6函数
    k.set6(&k, 0x60000000, 0, 0, 64, 0x60);
    return 0;
}

内容的提问来源于stack exchange,提问作者Steven Vanhaeren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 18:54:52