利用函数指针实现C的回调函数,实现调用者和底层驱动的解耦 第二种方式

简介: 利用函数指针实现C的回调函数,实现调用者和底层驱动的解耦 第二种方式

新建空项目,命名为RF_Drive,这个作为底层的驱动。

tt.png

添加MyDrive.c文件,向文件中添加代码,模拟驱动一些函数,代码如下:


思路:


EncData和DecData实现信息的加密和解密,由于不同厂家的设备,加密和解密的方式不同,所以不能在底层驱动中实现,需要不同的厂家在自己的函数库中实现。厂家和驱动约定好相同的接口,将函数通过指针通过调用socketclient_SetEncDataCallback函数,提前将函数存放到Sck_Handle里面。


#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "MyDrive.h"
typedef struct _Sck_Handle
{
    char    version[16];
    char    ip[16];
    int     port;
    unsigned char *p;
    int         len;
    char        *p2;
    EncData  Hw_EncData;
}Sck_Handle;
int  socketclient_SetEncDataCallback(void *handle, EncData Hw_EncData)
{
    int ret = 0;
    Sck_Handle  *tmpHandle = NULL;
    if (handle == NULL || Hw_EncData == NULL)
    {
        ret = -1;
        printf("func socketclient_SetEncDataCallback() err :%d  check handle == NULL err \n", ret);
        return ret;
    }
    tmpHandle = (Sck_Handle *)handle;
    tmpHandle->Hw_EncData = Hw_EncData;//提前把回调函数的入口地址 缓存到 句柄handle 上下文中
    return 0;
}
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;
}
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;
    if (tmpHandle->Hw_EncData != NULL) //如果设置了加密函数 则发送报文之前 先对数据进行加密
    {
        unsigned char crypdata[4096];
        int cryptdatalen = 4096;
        ret = tmpHandle->Hw_EncData(buf, buflen, crypdata, &cryptdatalen);
        if (ret != 0)
        {
            printf("func Hw_EncData() err :%d  \n", ret);
            return ret;
        }
        tmpHandle->len = cryptdatalen;
        tmpHandle->p = (unsigned char *)malloc(cryptdatalen);
        if (tmpHandle->p == NULL)
        {
            ret = -1;
            printf("func Hw_EncData() err :%d malloc err \n", ret);
            return ret;
        }
        memcpy(tmpHandle->p, crypdata, cryptdatalen); //缓存密文
    }
    else
    {
        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;
}
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;
}
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;
}
目录
相关文章
|
27天前
指针(5)---回调函数
指针(5)---回调函数
15 0
|
1月前
|
编译器 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(下)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
25 0
|
29天前
|
算法 搜索推荐 C语言
c函数指针与回调函数
c函数指针与回调函数
22 2
|
1月前
|
算法 搜索推荐 程序员
C语言中的函数指针和回调函数
C语言中的函数指针和回调函数
15 2
|
1月前
|
存储 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(中)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
26 0
|
1月前
|
存储 C语言 C++
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(上)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
17 0
|
1月前
|
存储 C语言
c语言函数指针和指针函数的区别,以及回调函数的使用。
c语言函数指针和指针函数的区别,以及回调函数的使用。
19 0
|
1月前
|
存储 程序员 API
C函数指针与回调函数
C函数指针与回调函数
29 0
|
1月前
|
C语言 C++
C语言之指针进阶篇_回调函数(3)
C语言之指针进阶篇_回调函数(3)
29 0
|
1月前
|
编译器 C++
函数指针和回调函数对函数取地址和直接使用函数名的差距
函数指针和回调函数对函数取地址和直接使用函数名的差距
66 0