利用函数指针实现C的回调函数,实现调用者和底层驱动的解耦
【摘要】
新建空项目,命名为RF_Drive,这个作为底层的驱动。
添加MyDrive.c文件,向文件中添加代码,模拟驱动一些函数,代码如下:
思路:
EncData和DecData实现信息的加密和解密,由于不同厂家的设备,加密和解密的方式不同,所以不能在底层驱动中实现,需要不同的厂家在自己的函数库中实现。厂家和驱动约定好相...
- 新建空项目,命名为RF_Drive,这个作为底层的驱动。
- 添加MyDrive.c文件,向文件中添加代码,模拟驱动一些函数,代码如下:
思路:
EncData和DecData实现信息的加密和解密,由于不同厂家的设备,加密和解密的方式不同,所以不能在底层驱动中实现,需要不同的厂家在自己的函数库中实现。厂家和驱动约定好相同的接口,将函数通过指针传进来,实现函数的回调。
-
#define _CRT_SECURE_NO_WARNINGS
-
-
#include <stdlib.h>
-
-
#include <string.h>
-
-
#include <stdio.h>
-
-
//完成发送报文的时候,进行数据加密
-
-
//定义函数指针类型 通过函数指针类型 来约定 厂商 去实现 加密解密函数的原型
-
-
typedef int(*EncData)(unsigned char *in, int inlen, unsigned char *out, int *outlen);
-
-
-
-
typedef int(*DecData)(unsigned char *in, int inlen, unsigned char *out, int *outlen);
-
-
-
-
typedef struct _Sck_Handle
-
-
{
-
-
char version[16];
-
-
char ip[16];
-
-
int port;
-
-
unsigned char *p;
-
-
int len;
-
-
char *p2;
-
-
}Sck_Handle;
-
-
-
-
int socketclient_sendAndEnc1(void *handle, unsigned char *buf, int buflen, EncData encDataCallback)
-
-
{
-
-
int ret = 0;
-
-
unsigned char cryptbuf[4096];
-
-
int cryptbuflen = 4096;
-
-
Sck_Handle *tmpHandle = NULL;
-
-
if (handle == NULL || buf == NULL || encDataCallback == NULL)
-
-
{
-
-
ret = -1;
-
-
printf("func socketclient_sendAndEnc1() err :%d check handle == NULL err \n", ret);
-
-
return ret;
-
-
}
-
-
ret = encDataCallback(buf, buflen, cryptbuf, &cryptbuflen); //间接的调用子任务
-
-
if (ret != 0)
-
-
{
-
-
ret = -2;
-
-
printf("func socketclient_sendAndEnc1() err :%d check handle == NULL err \n", ret);
-
-
return ret;
-
-
}
-
-
tmpHandle = (Sck_Handle *)handle;
-
-
tmpHandle->len = cryptbuflen;
-
-
tmpHandle->p = (unsigned char *)malloc(cryptbuflen);
-
-
if (tmpHandle->p == NULL)
-
-
{
-
-
ret = -3;
-
-
printf("func socketclient_sendAndEnc1() err :%d mallocerr \n", ret);
-
-
return ret;
-
-
}
-
-
//把加密的明文 缓存到 内存中
-
-
memcpy(tmpHandle->p, cryptbuf, cryptbuflen);
-
-
return 0;
-
-
}
-
-
//socket客户端环境初始化
-
-
int socketclient_init(void **handle)
-
-
{
-
-
int ret = 0;
-
-
Sck_Handle *tmpHandle = NULL;
-
-
if (handle == NULL)
-
-
{
-
-
ret = -1;
-
-
printf("func socketclient_init() err :%d check handle == NULL err \n", ret);
-
-
return ret;
-
-
}
-
-
tmpHandle = (Sck_Handle *)malloc(sizeof(Sck_Handle));
-
-
if (tmpHandle == NULL)
-
-
{
-
-
ret = -2;
-
-
printf("func socketclient_init() err :%d malloc err \n", ret);
-
-
return ret;
-
-
}
-
-
memset(tmpHandle, 0, sizeof(Sck_Handle));
-
-
strcpy(tmpHandle->version, "1.0.0.1");
-
-
strcpy(tmpHandle->ip, "192.168.12.12");
-
-
tmpHandle->port = 8081;
-
-
//间接赋值
-
-
*handle = tmpHandle;
-
-
return ret;
-
-
}
-
-
//socket报文发送
-
-
int socketclient_send(void *handle, unsigned char *buf, int buflen)
-
-
{
-
-
int ret = 0;
-
-
Sck_Handle *tmpHandle = NULL;
-
-
if (handle == NULL || buf == NULL || buflen <= 0)
-
-
{
-
-
ret = -2;
-
-
printf("func socketclient_send() err :%d (handle == NULL || buf==NULL || buflen <=0 ) \n", ret);
-
-
return ret;
-
-
}
-
-
tmpHandle = (Sck_Handle *)handle;
-
-
tmpHandle->len = buflen;
-
-
tmpHandle->p = (unsigned char *)malloc(buflen);
-
-
if (tmpHandle->p == NULL)
-
-
{
-
-
ret = -2;
-
-
printf("func socketclient_send() err :%d malloc len:%d \n", ret, buflen);
-
-
return ret;
-
-
}
-
-
memcpy(tmpHandle->p, buf, buflen); //数据的缓存到内存
-
-
return ret;
-
-
}
-
-
//socket报文接受
-
-
int socketclient_recv(void *handle, unsigned char *buf, int *buflen)
-
-
{
-
-
int ret = 0;
-
-
Sck_Handle *tmpHandle = NULL;
-
-
if (handle == NULL || buf == NULL || buflen == NULL)
-
-
{
-
-
ret = -2;
-
-
printf("func socketclient_recv() err :%d (handle == NULL || buf==NULL || buflen==NULL ) \n", ret);
-
-
return ret;
-
-
}
-
-
tmpHandle = (Sck_Handle *)handle;
-
-
memcpy(buf, tmpHandle->p, tmpHandle->len);
-
-
*buflen = tmpHandle->len; //间接赋值 告诉调用者 收到的数据的长度
-
-
return ret;
-
-
}
-
-
//socket环境释放
-
-
-
-
int socketclient_destory(void *handle)
-
-
{
-
-
int ret = 0;
-
-
Sck_Handle *tmpHandle = NULL;
-
-
if (handle == NULL)
-
-
{
-
-
return -1;
-
-
}
-
-
tmpHandle = (Sck_Handle *)handle;
-
-
if (tmpHandle->p != NULL)
-
-
{
-
-
free(tmpHandle->p); //释放结构体 成员域的 指针所指向的内存空间
-
-
}
-
-
free(tmpHandle); //释放结构体内存
-
-
return 0;
-
-
}
- 添加MyDrive.h文件。
完成后,右键项目,将配置类型改为dll动态链接库。
- 新建TestDrive工程,测试底层dll。将生成的RF_Drive.dll、RF_Drive.lib和MyDrive.h文件放到工程目录下面。
- 将RF_Drive链接到TestDrive。选择输入,然后选择附加依赖项,将RF_Drive.lib添加进去,然后点击确定。
- 将MyDrive.h包含到项目,然后新建Test.c文件,在Test.c中写入测试代码。代码如下:
-
#ifndef _INC_MYDRIVE_H__
-
-
#define _INC_MYDRIVE_H__
-
-
-
-
#define Import_SSS
-
-
-
-
#ifdef Import_SSS
-
-
#define API _declspec(dllexport)
-
-
#else
-
-
#define API _declspec(dllimport)
-
-
-
-
#endif
-
-
-
-
#ifdef __cplusplus
-
-
extern "C" {
-
-
#endif
-
-
-
-
//1 数据类型的封装
-
-
//2 handle的概念: 底层库的内存资源,记录着函数运行的上下文信息..
-
-
//3 底层库提供的是一种机制, 而不是满足某一个人的策略
-
-
-
-
//完成发送报文的时候,进行数据加密
-
-
//定义函数指针类型 通过函数指针类型 来约定 厂商 去实现 加密解密函数的原型
-
-
typedef int(*EncData)(unsigned char *in, int inlen, unsigned char *out, int *outlen);
-
-
typedef int(*DecData)(unsigned char *in, int inlen, unsigned char *out, int *outlen);
-
-
API
-
-
int socketclient_init(void **handle);
-
-
API
-
-
int socketclient_send(void *handle, unsigned char *buf, int buflen);
-
-
API
-
-
int socketclient_sendAndEnc1(void *handle, unsigned char *buf, int buflen, EncData encDataCallback);
-
-
API
-
-
int socketclient_recv(void *handle, unsigned char *buf, int *buflen);
-
-
API
-
-
int socketclient_destory(void *handle);
-
-
-
-
#ifdef __cplusplus
-
-
}
-
-
#endif
-
-
-
-
#endif
思路:
在调用者实现加密算法Hw_EncData,不同的调用者,实现加密算法的方式不同,需要调用者自己实现,然后将函数的指针传递给底层驱动。
-
#define _CRT_SECURE_NO_WARNINGS
-
-
#include <stdlib.h>
-
-
#include <string.h>
-
-
#include <stdio.h>
-
-
#include "MyDrive.h"
-
-
-
-
int Hw_EncData(unsigned char *in, int inlen, unsigned char *out, int *outlen)
-
-
{
-
-
printf("func Hw_EncData begin....\n ");
-
-
strcpy((char *)out, "123456789");
-
-
*outlen = 9;
-
-
printf("func Hw_EncData end....\n ");
-
-
return 0;
-
-
}
-
-
-
-
void main()
-
-
{
-
-
unsigned char buf[1024];
-
-
int buflen;
-
-
unsigned char out[1024];
-
-
int outlen;
-
-
void *handle = NULL;
-
-
int ret = 0;
-
-
strcpy((char *)buf, "aaaaaaaaaffffffffdddddddd");
-
-
buflen = 9;
-
-
//客户端初始化 获取handle上下
-
-
ret = socketclient_init(&handle /*out*/);
-
-
if (ret != 0)
-
-
{
-
-
printf("func socketclient_init() err:%d \n ", ret);
-
-
goto End;
-
-
}
-
-
//客户端发报文
-
-
//ret = socketclient_send(handle /*in*/, buf /*in*/, buflen /*in*/);
-
-
ret = socketclient_sendAndEnc1(handle, buf, buflen, Hw_EncData);
-
-
if (ret != 0)
-
-
{
-
-
printf("func socketclient_send() err:%d \n ", ret);
-
-
goto End;
-
-
}
-
-
//客户端收报文
-
-
ret = socketclient_recv(handle /*in*/, out /*in*/, &outlen/*in out*/);
-
-
if (ret != 0)
-
-
{
-
-
printf("func socketclient_recv() err:%d \n ", ret);
-
-
goto End;
-
-
}
-
-
End:
-
-
//客户端释放资源
-
-
ret = socketclient_destory(handle/*in*/);
-
-
printf("hello...\n");
-
-
system("pause");
-
-
printf("hello...\n");
-
-
system("pause");
-
-
return;
-
-
}
运行结果如下:
代码:https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/12898322
文章来源: wanghao.blog.csdn.net,作者:AI浩,版权归原作者所有,如需转载,请联系作者。
原文链接:wanghao.blog.csdn.net/article/details/108870746
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)