函数指针成员是可变参函数:函数指针数组里的成员是参数各不相同的函数

来源:互联网 发布:2017华为java编码规范 编辑:程序博客网 时间:2024/06/09 17:53

api_public.h

/定义函数指针数组的下标号*/

enum {

       API_RSVD =0,

       API_GETC,

       API_PUTC,

       API_TSTC,

       API_PUTS,

       API_RESET,

       API_GET_SYS_INFO,

       API_UDELAY,

       API_GET_TIMER,

       API_DEV_ENUM,

       API_DEV_OPEN,

       API_DEV_CLOSE,

       API_DEV_READ,

       API_DEV_WRITE,

       API_ENV_ENUM,

       API_ENV_GET,

       API_ENV_SET,

       API_MAXCALL

};

Api.c

#include <api_public.h>

typedef  int(*cfp_t)(va_list argp);

/*指针数组里某一个函数的定义*/

static int API_dev_read(va_list ap)

{

       structdevice_info *di;

       void *buf;

       lbasize_t*len_stor, *act_len_stor;

       lbastart_t*start;

       int*len_net, *act_len_net;

       /* 1. argis ptr to the device_info struct */

       di =(struct device_info *)va_arg(ap,u_int32_t);/*指针大小都是4字节大小,所以可以用32位数据大小来接收可变参数struct device_info *di*/

       if (di ==NULL)

              returnAPI_EINVAL;

       /* XXXshould we check if device is open? i.e. the ->state ? */

       if(di->cookie == NULL)

              returnAPI_ENODEV;

       /* 2. argis ptr to buffer from where to put the read data */

       buf =(void *)va_arg(ap,u_int32_t);//接收可变参数void *buf

       if (buf ==NULL)

              returnAPI_EINVAL;

       if(di->type & DEV_TYP_STOR) {

              /*3. arg - ptr to var with # of blocks to read */

              len_stor= (lbasize_t *)va_arg(ap,u_int32_t);

              if(!len_stor)

                     returnAPI_EINVAL;

              if(*len_stor <= 0)

                     returnAPI_EINVAL;

              /*4. arg - ptr to var with start block */

              start= (lbastart_t *)va_arg(ap,u_int32_t);

              /*5. arg - ptr to var where to put the len actually read */

              act_len_stor= (lbasize_t *)va_arg(ap, u_int32_t);

              if(!act_len_stor)

                     returnAPI_EINVAL;

              *act_len_stor= dev_read_stor(di->cookie, buf, *len_stor, *start);

       } else if(di->type & DEV_TYP_NET) {

              /*3. arg points to the var with length of packet to read */

              len_net= (int *)va_arg(ap,u_int32_t);

              if(!len_net)

                     returnAPI_EINVAL;

              if(*len_net <= 0)

                     returnAPI_EINVAL;

              /*4. - ptr to var where to put the len actually read */

              act_len_net= (int *)va_arg(ap,u_int32_t);

              if(!act_len_net)

                     returnAPI_EINVAL;

              *act_len_net= dev_read_net(di->cookie, buf, *len_net);

       } else

              returnAPI_ENODEV;

       return 0;

}

static cfp_t calls_table[API_MAXCALL] = {NULL, };//只初始化第一个成员

/*初始化数组*/

void api_init(void)

{

       structapi_signature *sig = NULL;

       /* TODOput this into linker set one day... */

       calls_table[API_RSVD]= NULL;

       calls_table[API_GETC]= &API_getc;

       calls_table[API_PUTC]= &API_putc;

       calls_table[API_TSTC]= &API_tstc;

       calls_table[API_PUTS]= &API_puts;

       calls_table[API_RESET]= &API_reset;

       calls_table[API_GET_SYS_INFO]= &API_get_sys_info;

       calls_table[API_UDELAY]= &API_udelay;

       calls_table[API_GET_TIMER]= &API_get_timer;

       calls_table[API_DEV_ENUM]= &API_dev_enum;

       calls_table[API_DEV_OPEN]= &API_dev_open;

       calls_table[API_DEV_CLOSE]= &API_dev_close;

       calls_table[API_DEV_READ] = &API_dev_read;

       calls_table[API_DEV_WRITE]= &API_dev_write;

       calls_table[API_ENV_GET]= &API_env_get;

       calls_table[API_ENV_SET]= &API_env_set;

       calls_table[API_ENV_ENUM]= &API_env_enum;

       calls_no =API_MAXCALL;

/*可变参函数*/

int syscall(intcall, int *retval, ...)

{

       va_list    ap;

       int rv;

       if (call< 0 || call >= calls_no) {

              debugf("invalidcall #%d\n", call);

              return0;

       }

       if(calls_table[call] == NULL) {

              debugf("syscall#%d does not have a handler\n", call);

              return0;

       }

       va_start(ap, retval); //通过va_startretval中读取参数

       rv =calls_table[call](ap);//调用指针数组里的函数

       if (retval!= NULL)//用户如果不想返回数据就带入参数指针为NULL

              *retval= rv;

       return 1;

}

/*调用可变参函数*/

int ub_dev_read(inthandle, void *buf, lbasize_t len, lbastart_t start, lbasize_t *rlen)

{

       structdevice_info *di;

       lbasize_tact_len;

       int err =0;

       if(!dev_stor_valid(handle))

              returnAPI_ENODEV;

       di =&devices[handle];

       if(!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))

              returnAPI_ESYSC;

       if (!err&& rlen)

              *rlen= act_len;

       returnerr;

}

函数指针数组里的成员是参数各不相同的函数,即成员是可变参函数。

 

 

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一方坚决不同意离婚我该怎么办 模拟农场车翻了怎么办 手机退出键坏了怎么办 dnf邮件发错了怎么办 手机提示sd卡已损坏怎么办 解压包文件数据损坏该怎么办 电脑被压缩后电脑打不开怎么办 眼睛里进了飞虫怎么办 虫子飞到眼睛里怎么办 云电脑pc版双鼠标怎么办 电脑蓝屏代码7f怎么办 笔记本电脑蓝屏开不了机怎么办 装xp系统后蓝屏怎么办 一键ghost断电了怎么办 如何防止cpu降频怎么办 win7 64位系统不兼容怎么办 网页无法加载打印机插件怎么办 微信提示安装了插件怎么办 电脑上不了网怎么办 win10 win10电脑突然没网了怎么办 笔记本玩战争前线发热严重怎么办 玩战争前线总是闪退怎么办 uu加速器卡在29怎么办 新ipad下载不了东西怎么办 福昕pdf阅读器找不到图章怎么办 战地4没达到分数怎么办 植物在太暗环境怎么办 玩绝地求生机型不支持怎么办 安卓安装包损坏怎么办 方舟手游安装包损坏怎么办 7p新机耗电快怎么办 不小心把图片删了怎么办 腿上毛又长又多怎么办 征兵体检体重太轻怎么办 体检发现颈部有淋巴节怎么办? 4岁宝宝汗毛重怎么办 嘴巴张开闭不上怎么办 口张开闭不上怎么办 要去当兵有痔疮怎么办 狗舔的东西吃了怎么办 婚检说生过孩子怎么办