函数指针成员是可变参函数:函数指针数组里的成员是参数各不相同的函数
来源:互联网 发布: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_start从retval中读取参数
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;
}
函数指针数组里的成员是参数各不相同的函数,即成员是可变参函数。
- 函数指针成员是可变参函数:函数指针数组里的成员是参数各不相同的函数
- 成员函数的指针
- 成员函数的指针
- 成员函数指针并不是指针
- 类的成员函数指针作为参数传递给其他函数和普通函数指针的传递是不同的
- 类的成员函数指针作为参数传递给其他函数和普通函数指针的传递是不同的
- 成员函数指针数组
- 成员函数指针数组
- 成员函数指针数组
- 带成员函数指针的成员函数
- 函数的参数是指针
- 为什么 C++ 成员函数指针是 16 字节宽的
- 指针类型作为成员函数的参数
- 指针类型作为成员函数的参数
- 指针类型作为成员函数的参数
- 指针类型作为成员函数的参数
- 指向成员函数的指针
- 类成员函数的指针
- 瞬时单表高并发访问的解决方法(支持事物)
- Ubuntu设置apt代理
- javaScript基础
- Validator验证框架
- Flink Configuration简介
- 函数指针成员是可变参函数:函数指针数组里的成员是参数各不相同的函数
- Android NDK开发指南(二)Android.mk文件
- 递归讲解(python)
- tensorflow使用BN—Batch Normalization
- 设置窗体的标题栏
- nginx服务器配置:nginx.pid" failed (2: No such file or directory
- 自定义View 基础, bitmap
- java多线程系列(六)---线程池原理及其使用
- html中想要将背景颜色渐变怎么弄?