前言
所有技术的学习,第一步都是先整理招式,等招式熟练了,再学习内功。最后融会贯通。这次整理一下公司代码中函数指针的用法。
第一步:定义一个回调函数
注意到:
1、输入参数是void *型,这样好处是今后如果只想传入一个参数,那直接char *强转即可,如果涉及到多个参数,可以定一个结构进去,真正做到函数通用
2、输出参数是void **好处自然不用说,输出的内容完全自己定义
3、下面的函数指针通用性很强
typedef int (*hikos_callback) (
enum storage_action_e action_e, const long id, void *inbuffer, void **outbuffer);
第二步:公共函数调用回调函数
1、定义一个公共函数来调用上述函数指针,可以让多个小组协同开发
2、公共函数的后续参数,都是函数指针的参数
ret = hikos_storage(hikos_ceph, global_action, global_command, global_inbuffer, (void *)&outbuffer);
公共函数 函数实现
int hikos_storage(hikos_callback callback_f,
enum storage_action_e action_e, const long id, void *inbuffer, void **outbuffer)
{
int ret = 0;
int fd = -1;
int file_seek = 0;
cs_file_t *p_cs_file = NULL;
int action_value = 0;
long command_value = 0;
char command_str[64] = {0};
p_cs_file = malloc(sizeof(cs_file_t));
if (!p_cs_file)
{
common_print(PRINT_ALERT, "malloc error");
ret = ERROR_MALLOC;
goto out;
}
memset(p_cs_file, 0, sizeof(cs_file_t));
fd = open(STORAGE_CS_PATH, O_RDONLY);
if (-1 == fd)
{
common_print(PRINT_ALERT, "%s: open error", STORAGE_CS_PATH);
ret = ERROR_PATH;
goto out;
}
flock(fd, LOCK_EX);
while (sizeof(cs_file_t) == pread(fd, p_cs_file, sizeof(cs_file_t), file_seek))
{
if (!strcmp(p_cs_file->api_action, "get"))
{
action_value = STORAGE_ACTION_GET;
}
else if (!strcmp(p_cs_file->api_action, "add"))
{
action_value = STORAGE_ACTION_ADD;
}
else if (!strcmp(p_cs_file->api_action, "set"))
{
action_value = STORAGE_ACTION_SET;
}
else if (!strcmp(p_cs_file->api_action, "del"))
{
action_value = STORAGE_ACTION_DEL;
}
else if (!strcmp(p_cs_file->api_action, "chk"))
{
action_value = STORAGE_ACTION_CHK;
}
sscanf(p_cs_file->api_command, "%lx:%s", &command_value, command_str);
if (action_e == action_value && id == command_value)
{
if (1 == p_cs_file->api_enable)
{
flock(fd, LOCK_UN);
ret = callback_f(action_e, id, inbuffer, (void *)outbuffer);
goto out;
}
else
{
ret = ERROR_DISABLE;
}
break;
}
file_seek += sizeof(cs_file_t);
memset(p_cs_file, 0, sizeof(cs_file_t));
}
flock(fd, LOCK_UN);
out:
if (-1 != fd)
{
close(fd);
fd = -1;
}
if (p_cs_file)
{
free(p_cs_file);
p_cs_file = NULL;
}
return ret;
}
第三步:举例其中一个小组子模块
1、使用枚举来控制功能分类
int hikos_ceph(
enum storage_action_e action_e, const long id, void *inbuffer, void **outbuffer)
{
int ret = -1;
switch (action_e)
{
case STORAGE_ACTION_GET:
ret = ceph_get(id, inbuffer, outbuffer);
break;
case STORAGE_ACTION_ADD:
ret = ceph_add(id, inbuffer, outbuffer);
break;
case STORAGE_ACTION_SET:
ret = ceph_set(id, inbuffer, outbuffer);
break;
case STORAGE_ACTION_DEL:
ret = ceph_del(id, inbuffer, outbuffer);
break;
case STORAGE_ACTION_CHK:
ret = ceph_chk(id, inbuffer, outbuffer);
break;
default:
goto out;
}
return ret;
out:
return ret;
}
第四步:再用id控制小组各个成员开发
static int ceph_add(const long id, void *inbuffer, void **outbuffer)
{
int ret = -1;
switch (id)
{
case 0x00112000:
break;
case CEPH_CLUSTER_ADD_NODE:
ret = ceph_add_node(inbuffer, outbuffer);
break;
case CEPH_POOL_CREATE:
ret = ceph_pool_create(inbuffer,NULL);
break;
case CEPH_POOL_EXPAND:
ret = ceph_pool_expand(inbuffer,NULL);
break;
default:
ret = ERROR_UNKNOW;
goto out;
}
return ret;
out:
return ret;
}
/* ceph 模块命令 */
typedef enum
{
CEPH_RPM_INSTALL = 0x00130000, /*安装ceph rpm 包*/
CEPH_RPM_STATUS, /*ceph安装包状态*/
CEPH_CLUSTER_CREATE, /*ceph集群创建*/
CEPH_CLUSTER_ADD_NODE, /*ceph集群扩容*/
CEPH_CLUSTER_CREATE_PRO,
CEPH_CLUSTER_ADD_NODE_PRO,
CEPH_PURE_DEPLOY_PROGRESS,
CEPH_CLUSTER_ERROR = 0x00130FFF,
CEPH_DISK_GET_DISK_LIST = 0x00131000, /*获取ceph可用磁盘列表*/
CEPH_DISK_DEL_POOL_DISK, /*删除存储池的磁盘*/
CEPH_DISK_GET_OSD_INFO, /*获取osd状态信息*/
CEPH_DISK_ERROR = 0x00131FFF, /* 未知命令码*/
CEPH_POOL_CREATE = 0x00132001, /*ceph存储池创建*/
CEPH_POOL_EXPAND, /* ceph存储池扩容*/
CEPH_POOL_LIST, /*ceph存储池列表*/
CEPH_POOL_DETAIL, /*ceph存储池详情*/
CEPH_POOL_DELETE, /*ceph删除存储池*/
CEPH_POOL_PERFORMANCE, /*pool性能采集*/
CEPH_POOL_PROGRESS, /*进度信息*/
CEPH_POOL_ERROR = 0x00132FFF,
CEPH_ALARM_CLUSTER = 0x00133001, /* ceph集群告警 */
CEPH_ALARM_CAPACITY, /* ceph容量告警 */
CEPH_ALARM_ERROR = 0x00133FFF
}CEPH_COMMAND_E;
版权声明:本文为qq_23929673原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。