最近看ipmitool源码,发现里面有段令人费解的代码,查了很长时间才查到资料,主要还是对C不太熟悉,查都不知道怎么下手,最后搜索C语言结构体初始化找到了答案。感谢这篇文章的博主https://www.cnblogs.com/wxmdevelop/p/8435792.html
代码如下:
struct ipmi_intf ipmi_lanplus_intf = {
name: "lanplus",
desc: "IPMI v2.0 RMCP+ LAN Interface",
setup: ipmi_lanplus_setup,
open: ipmi_lanplus_open,
close: ipmi_lanplus_close,
sendrecv: ipmi_lanplus_send_ipmi_cmd,
recv_sol: ipmi_lanplus_recv_sol,
send_sol: ipmi_lanplus_send_sol,
keepalive: ipmi_lanplus_keepalive,
set_max_request_data_size: ipmi_lanp_set_max_rq_data_size,
set_max_response_data_size: ipmi_lanp_set_max_rp_data_size,
target_addr: IPMI_BMC_SLAVE_ADDR,
};
C语言里面用到冒号的地方其实很少,除了case语句,结构体定义时限制成员位域,还有今天这种结构体的初始化。
结构体ipmi_intf预先就定义好了,包括一些普通变量、结构体指针变量以及函数指针变量。
struct ipmi_intf {
char name[16]; #声明一个叫name的char类型指针变量
char desc[128];
char *devfile;
int fd; #int类型指针变量
int opened;
int abort;
int noanswer;
int picmg_avail;
IPMI_OEM manufacturer_id; #自定义IPMI_OEM类型的指针变量
struct ipmi_session * session; #结构体类型指针变量
struct ipmi_oem_handle * oem;
struct ipmi_cmd * cmdlist;
uint8_t target_ipmb_addr; #uint8_t类型的指针变量
uint32_t my_addr;
uint32_t target_addr;
uint8_t target_lun;
uint8_t target_channel;
uint32_t transit_addr;
uint8_t transit_channel;
uint16_t max_request_data_size;
uint16_t max_response_data_size;
uint8_t devnum;
int (*setup)(struct ipmi_intf * intf); #声明一个返回值类型是int型的函数指针变量
int (*open)(struct ipmi_intf * intf);
void (*close)(struct ipmi_intf * intf);
struct ipmi_rs *(*sendrecv)(struct ipmi_intf * intf, struct ipmi_rq * req);
int (*sendrsp)(struct ipmi_intf * intf, struct ipmi_rs * rsp);
struct ipmi_rs *(*recv_sol)(struct ipmi_intf * intf);
struct ipmi_rs *(*send_sol)(struct ipmi_intf * intf, struct ipmi_v2_payload * payload);
int (*keepalive)(struct ipmi_intf * intf);
int (*set_my_addr)(struct ipmi_intf * intf, uint8_t addr);
void (*set_max_request_data_size)(struct ipmi_intf * intf, uint16_t size);
void (*set_max_response_data_size)(struct ipmi_intf * intf, uint16_t size);
};
struct ipmi_intf ipmi_lanplus_intf ={....},这是在实例化ipmi_intf结构体,创建一个ipmi_lanplus_intf的结构体实例,后面的“=”,是准备给这个实例赋初值,也就是初始化。
从上面两段代码,很明显可以看出ipmi_lanplus_intf这个实例在初始化时只给小部分成员变量赋值了。所以采用这种冒号的方式可以实现结构体实例的并不完全初始化。