C语言复杂结构体里面变量的调用

这里截取ipmitool Windows 1.8.18的部分代码做说明。

struct ipmi_rs {
	uint8_t ccode;
	uint8_t data[IPMI_BUF_SIZE];

	int data_len;

	struct {
		uint8_t netfn;
		uint8_t cmd;
		uint8_t seq;
		uint8_t lun;
	} msg;

	struct {
		uint8_t authtype;
		uint32_t seq;
		uint32_t id;
		uint8_t bEncrypted;	/* IPMI v2 only */
		uint8_t bAuthenticated;	/* IPMI v2 only */
		uint8_t payloadtype;	/* IPMI v2 only */
		uint16_t msglen;
	} session;

	union {
		struct {
			uint8_t rq_addr;
			uint8_t netfn;
			uint8_t rq_lun;
			uint8_t rs_addr;
			uint8_t rq_seq;
			uint8_t rs_lun;
			uint8_t cmd;
		} ipmi_response;
		struct {
			uint8_t message_tag;
			uint8_t rakp_return_code;
			uint8_t max_priv_level;
			uint32_t console_id;
			uint32_t bmc_id;
			uint8_t auth_alg;
			uint8_t integrity_alg;
			uint8_t crypt_alg;
		} open_session_response;
		struct {
			uint8_t message_tag;
			uint8_t rakp_return_code;
			uint32_t console_id;
			uint8_t bmc_rand[16];	/* Random number generated by the BMC */
			uint8_t bmc_guid[16];
			uint8_t key_exchange_auth_code[20];
		} rakp2_message;
		struct {
			uint8_t message_tag;
			uint8_t rakp_return_code;
			uint32_t console_id;
			uint8_t integrity_check_value[20];
		} rakp4_message;
		struct {
			uint8_t packet_sequence_number;
			uint8_t acked_packet_number;
			uint8_t accepted_character_count;
			uint8_t is_nack;	/* bool */
			uint8_t transfer_unavailable;	/* bool */
			uint8_t sol_inactive;	/* bool */
			uint8_t transmit_overrun;	/* bool */
			uint8_t break_detected;	/* bool */
		} sol_packet;
	} payload;
};

这段代码不算太复杂,结构体成员里面没有涉及到指针变量,只是有关于结构体的嵌套,结构体含成员union等,本文主要讲解如何层级访问和调用结构体里面的变量。先创建上面结构体实例。

struct ipmi_rs * rsp;             #创建ipmi_rs结构体指针
rsp = ipmi_lan_recv_packet(intf); #ipmi_lan_recv_packet()函数返回的是结构体首地址,并将该结构体的首地址赋给rsp指针

这里ipmi_lan_recv_packet()函数不做说明,它是ipmitool里面定义的函数,该函数返回的是ipmi_rs类型的结构体的地址,而指针就是指向地址的,所以可以将返回值赋给指针变量rsp。

可以通俗的打个比喻,这个结构体就像零食大礼包,大礼包名字叫旺旺,等同于结构体的ipmi_rs,里面有不同类型的零食,类似于结构体里定义的不同类型的数据(int/char/bool等),然后被你买了回来,这时你告诉商家你的地址,就有一包这样的零食大礼包根据这个地址被寄到了你的手上,这个地址就是rsp,rsp指向的人就是你,当然可能还有其他吃货也买了这款零食大礼包,地址可以是rsp1、rsp2等等,一个地址相当于一个结构体实例。然后你拿到大礼包,打开一看,发现有的可以直接吃,有的还有嵌套的小包装,就像结构体里的嵌套。接下来就是你如何吃(调用)里面的东西了。

接下来我们要调用这个结构体里面不同层级的变量,这些变量在结构体里面的地位可分为三种情况:

1、可以直接吃的小零食,ccode、data[IPMI_BUF_SIZE]、 data_len这三个变量在结构体里地位一致,属于最外层的成员,可以如下访问并调用:

rsp->ccode
rsp->data[IPMI_BUF_SIZE]
rsp->data_len

2、拆开大礼包还有小包装的,msg、session、payload小包装里面的变量地位是一样的,可以这样访问(各取里面一个变量为例):

rsp->msg.netfn
rsp->session.authtype

3、这时发现payload小包装里面还有5个小袋子(ipmi_response、open_session_response、rakp2_message、rakp4_message、sol_packet),那就要再往下拆:

rsp->payload.ipmi_response.rq_addr

终于所有的零食都可以吃到了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值