zoukankan      html  css  js  c++  java
  • C语言 函数指针三(反向调用)

    动态库代码

    //简单的动态库开发----报文发送
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    //定义加密函数指针类型
    typedef int(*PDesEncSocket)(char *, int , char **, int *);
    //定义解密函数指针类型
    typedef int(*PDesDecSocket)(char *, int , char **, int *);
    
    //定义上下文结构体
    typedef struct _SCK_HANDLE{
        //定义报文IP
        char ipaddress[30];
        //定义报文端口
        char port[10];
        //定义报文接受数组
        unsigned char * buf;
        //定义报文长度
        int buflen;
        //定义加密函数指针变量
        PDesEncSocket pe;
        //定义解密函数指针变量
        PDesDecSocket pd;
    }SCK_HANDLE;
    
    //初始化上下文
    _declspec(dllexport)
    int cltSocketInit(void **handle/*out*/){
        int ERRO_MSG = 0;
        if (handle==NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL 报文初始化失败 erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //定义上下文指针
        SCK_HANDLE *shandle = NULL;
        //分配内存
        //详述:此处分配内存必须分配堆内存(malloc函数分配),这也正是malloc函数真正的用途所在
        //此处不可以分配栈内存,栈内存会被系统自动回收,但是报文的发送与接受所使用的上下文SCK_HANDLE,必须长时间存在
        //何时回收必须由用户决定,而不能随便的被回收
        //同样使用静态区也不合适,因为无法人为回收内存空间,必须等待电脑关机,综上所述,只能使用malloc函数分配内存
        shandle = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));
        //重置内存空间
        memset(shandle, 0, sizeof(SCK_HANDLE));
        strcpy(shandle->ipaddress,"192.168.0.128");
        strcpy(shandle->port, "88");
        *handle = shandle;
        return ERRO_MSG;
    }
    
    //注入加密函数指针
    _declspec(dllexport)
    int InjectionEnc(void *handle/*in*/, PDesEncSocket pein/*in*/){
        int ERRO_MSG = 0;
        if (handle == NULL||pein==NULL)
        {
            ERRO_MSG = 1;
            printf("handle == NULL||pein==NULL 传入参数不可以为空  erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        SCK_HANDLE* sh = (SCK_HANDLE*)handle;
        sh->pe = pein;
        return ERRO_MSG;
    }
    
    //注入解密函数指针
    _declspec(dllexport)
    int InjectionDec(void *handle/*in*/, PDesDecSocket pdin/*in*/){
        int ERRO_MSG = 0;
        if (handle == NULL || pdin == NULL)
        {
            ERRO_MSG = 1;
            printf("handle == NULL||pdin==NULL 传入参数不可以为空  erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        SCK_HANDLE* sh = (SCK_HANDLE*)handle;
        sh->pd = pdin;
        return ERRO_MSG;
    }
    
    //客户端发报文
    _declspec(dllexport)
    int cltSocketSend(void *handle/*in*/, unsigned char *buf/*in*/, int buflen/*in*/){
        int ERRO_MSG = 0;
        if (handle==NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL handle不可以为NULL erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (buf == NULL)
        {
            ERRO_MSG = 2;
            printf("buf==NULL buf不可以为NULL erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        SCK_HANDLE *sh = NULL;
        sh = (SCK_HANDLE *)handle;
        if (sh->pe == NULL)
        {
            ERRO_MSG = 3;
            printf("加密函数指针不可以为NULL erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //不需要为报文开辟内存,因为加密函数会分配内存
        sh->pe(buf, buflen, &sh->buf, &sh->buflen);
        return ERRO_MSG;
    }
    
    //客户端发报文方式二
    _declspec(dllexport)
    int cltSocketSend2(void *handle/*in*/, unsigned char *buf/*in*/, PDesEncSocket pein/*in*/, int buflen/*in*/){
        int ERRO_MSG = 0;
        if (handle == NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL handle不可以为NULL erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (buf == NULL)
        {
            ERRO_MSG = 2;
            printf("buf==NULL buf不可以为NULL erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (pein == NULL)
        {
            ERRO_MSG = 4;
            printf("pein==NULL 传入参数函数指针不可以为空 erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        SCK_HANDLE *sh = NULL;
        sh = (SCK_HANDLE *)handle;
        //不需要为报文开辟内存,因为加密函数会分配内存
        //函数指针加密
        pein(buf, buflen, &sh->buf, &sh->buflen);
        return ERRO_MSG;
    }
    
    //客户端收报文
    _declspec(dllexport)
    int cltSocketRev(void *handle/*in*/, unsigned char **buf/*out*/, int *buflen/*in*/){
        int ERRO_MSG = 0;
        if (handle == NULL || buf == NULL || buflen==NULL)
        {
            ERRO_MSG = 1;
            printf("handle == NULL || buf == NULL || buflen==NULL erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //定义临时上下文变量
        SCK_HANDLE *sh = NULL;
        sh = (SCK_HANDLE *)handle;
        //不需要分配返回报文的内存,这里有解密函数分配
        if (sh->pd==NULL)
        {
            ERRO_MSG = 2;
            printf("解密函数指针为空  erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //解密报文
        sh->pd(sh->buf, sh->buflen, buf, buflen);
        //释放上下文中字符串数组的内存空间(至于具体应用还是看场景)
        if (sh->buf!=NULL)
        {
            //释放内存
            free(sh->buf);
            //消除野指针
            sh->buf = NULL;
        }
        sh->buflen = 0;
        return ERRO_MSG;
    }
    
    //客户端收报文方式二
    _declspec(dllexport)
    int cltSocketRev2(void *handle/*in*/, unsigned char **buf/*out*/, PDesDecSocket pdin/*in*/, int *buflen/*in*/){
        int ERRO_MSG = 0;
        if (handle == NULL || buf == NULL || buflen == NULL)
        {
            ERRO_MSG = 1;
            printf("handle == NULL || buf == NULL || buflen==NULL erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (pdin==NULL)
        {
            ERRO_MSG = 2;
            printf("pdin == NULL  msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //定义临时上下文变量
        SCK_HANDLE *sh = NULL;
        sh = (SCK_HANDLE *)handle;
        //不需要分配返回报文的内存,这里有解密函数分配
        //解密报文
        pdin(sh->buf, sh->buflen, buf, buflen);
        //释放上下文中字符串数组的内存空间(至于具体应用还是看场景)
        if (sh->buf != NULL)
        {
            //释放内存
            free(sh->buf);
            //消除野指针
            sh->buf = NULL;
        }
        sh->buflen = 0;
        return ERRO_MSG;
    }
    
    //客户端释放资源
    _declspec(dllexport)
    int cltSocketDestory(void **handle){
        int ERRO_MSG = 0;
        if (handle==NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (*handle!=NULL)
        {
            //释放内存
            free(*handle);
            //消除野指针
            *handle = NULL;
        }
        return ERRO_MSG;
    }

    业务函数代码

    #ifndef _NZHANG
    #define _NZHANG
    //定义加密函数指针类型
    typedef int(*PDesEncSocket)(char *, int, char **, int *);
    //定义解密函数指针类型
    typedef int(*PDesDecSocket)(char *, int, char **, int *);
    //初始化上下文
    int cltSocketInit(void **handle/*out*/);
    //注入加密函数指针
    int InjectionEnc(void *handle/*in*/, PDesEncSocket pein/*in*/);
    //注入解密函数指针
    int InjectionDec(void *handle/*in*/, PDesDecSocket pdin/*in*/);
    //客户端发报文
    int cltSocketSend(void *handle/*in*/, unsigned char *buf/*in*/, int buflen/*in*/);
    //客户端发报文方式二
    int cltSocketSend2(void *handle/*in*/, unsigned char *buf/*in*/, PDesEncSocket pein/*in*/, int buflen/*in*/);
    //客户端收报文
    int cltSocketRev(void *handle/*in*/, unsigned char **buf/*out*/, int *buflen/*in*/);
    //客户端收报文方式二
    int cltSocketRev2(void *handle/*in*/, unsigned char **buf/*out*/, PDesDecSocket pdin/*in*/, int *buflen/*in*/);
    //客户端释放资源
    int cltSocketDestory(void **handle);
    
    #endif
    //函数指针的反向调用--增加加密解密函数
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include"des.h"
    #include"L001.h"
    
    /*
    利用函数指针指针实现多种加密方法加密报文
    */
    
    //加密函数1
    int DesEncSocket(char *plainstr/*in*/, int plainlen, char **cryptstr/*out*/, int *cryptlen){
        int ERRO_MSG = 0;
        if (plainstr == NULL || cryptstr == NULL || cryptlen == NULL)
        {
            ERRO_MSG = 1;
            printf("加密参数列表为空
    ");
            return ERRO_MSG;
        }
        //des密文比明文长,但是密文最多比明文多8个字节(所以我取10个足够)
        *cryptstr = (char *)malloc((sizeof(char)*plainlen) + 10);
        if (cryptstr == NULL)
        {
            ERRO_MSG = 2;
            printf("加密函数分配输出内存失败!
    ");
            return ERRO_MSG;
        }
        int ret = DesEnc((unsigned char *)plainstr, plainlen, (unsigned char *)*cryptstr, cryptlen);
        if (ret != 0)
        {
            ERRO_MSG = 3;
            printf("des加密函数执行失败!
    ");
            return ERRO_MSG;
        }
        return ERRO_MSG;
    }
    //解密函数1
    int DesDecSocket(char *cryptstr/*in*/, int cryptlen, char **plainstr/*out*/, int *plainlen){
        int ERRO_MSG = 0;
        if (plainstr == NULL || cryptstr == NULL || plainlen == NULL)
        {
            ERRO_MSG = 1;
            printf("解密参数列表为空!
    ");
            return ERRO_MSG;
        }
        //分配内存空间(des密文只可能比明文长)
        *plainstr = (char *)malloc((sizeof(char)*cryptlen));
        if (plainstr == NULL)
        {
            ERRO_MSG = 2;
            printf("分配输出内存失败!
    ");
            return ERRO_MSG;
        }
        int ret = DesDec((unsigned char *)cryptstr, cryptlen, (unsigned char *)*plainstr, plainlen);
        if (ret != 0)
        {
            ERRO_MSG = 3;
            printf("des解密函数执行失败!
    ");
            return ERRO_MSG;
        }
        return ERRO_MSG;
    }
    //加密函数2
    int DesEncSocket2(char *plainstr/*in*/, int plainlen, char **cryptstr/*out*/, int *cryptlen){
        int ERRO_MSG = 0;
        if (plainstr == NULL || cryptstr == NULL || cryptlen == NULL)
        {
            ERRO_MSG = 1;
            printf("加密参数列表为空
    ");
            return ERRO_MSG;
        }
        //des密文比明文长,但是密文最多比明文多8个字节(所以我取10个足够)
        *cryptstr = (char *)malloc((sizeof(char)*plainlen) + 10);
        if (cryptstr == NULL)
        {
            ERRO_MSG = 2;
            printf("加密函数分配输出内存失败!
    ");
            return ERRO_MSG;
        }
        int ret = DesEnc((unsigned char *)plainstr, plainlen, (unsigned char *)*cryptstr, cryptlen);
        if (ret != 0)
        {
            ERRO_MSG = 3;
            printf("des加密函数执行失败!
    ");
            return ERRO_MSG;
        }
        return ERRO_MSG;
    }
    //解密函数2
    int DesDecSocket2(char *cryptstr/*in*/, int cryptlen, char **plainstr/*out*/, int *plainlen){
        int ERRO_MSG = 0;
        if (plainstr == NULL || cryptstr == NULL || plainlen == NULL)
        {
            ERRO_MSG = 1;
            printf("解密参数列表为空!
    ");
            return ERRO_MSG;
        }
        //分配内存空间(des密文只可能比明文长)
        *plainstr = (char *)malloc((sizeof(char)*cryptlen));
        if (plainstr == NULL)
        {
            ERRO_MSG = 2;
            printf("分配输出内存失败!
    ");
            return ERRO_MSG;
        }
        int ret = DesDec((unsigned char *)cryptstr, cryptlen, (unsigned char *)*plainstr, plainlen);
        if (ret != 0)
        {
            ERRO_MSG = 3;
            printf("des解密函数执行失败!
    ");
            return ERRO_MSG;
        }
        return ERRO_MSG;
    }
    
    void ProtectA(){
        //定义发送报文
        char str1[30] = "1234567";
        //定义报文长度
        int buflen1 = strlen(str1) + 1;
        //定义接受报文变量
        char *buf = NULL;
        int len2 = 0;
        void *handle = NULL;
        int ret = 0;
        //初始化报文
        ret = cltSocketInit(&handle);
        if (ret != 0)
        {
            printf("初始化报文对象失败!
    ");
        }
        //注入加密函数指针
        ret = InjectionEnc(handle, DesEncSocket);
        if (ret != 0)
        {
            printf("注入加密函数指针失败!
    ");
        }
        //注入解密函数指针
        ret = InjectionDec(handle, DesDecSocket);
        if (ret != 0)
        {
            printf("注入解密函数指针失败!
    ");
        }
        //发送报文
        ret = cltSocketSend(handle, str1, buflen1);
        if (ret != 0)
        {
            printf("发送报文失败!
    ");
        }
        //接收报文
        ret = cltSocketRev(handle, &buf, &len2);
        if (ret != 0)
        {
            printf("接收报文失败!
    ");
        }
    
        //释放报文内存
        if (buf != NULL)
        {
            //打印报文
            printf(buf);
            free(buf);
            buf = NULL;
        }
        //释放报文对象
        ret = cltSocketDestory(&handle);
        if (ret != 0)
        {
            printf("释放报文对象失败!
    ");
        }
    }
    
    void ProtectB(){
        //定义发送报文
        char str1[30] = "1234567";
        //定义报文长度
        int buflen1 = strlen(str1) + 1;
        //定义接受报文变量
        char *buf = NULL;
        int len2 = 0;
        void *handle = NULL;
        int ret = 0;
        //初始化报文
        ret = cltSocketInit(&handle);
        if (ret != 0)
        {
            printf("初始化报文对象失败!
    ");
        }
        //发送报文
        ret = cltSocketSend2(handle, str1, DesEncSocket2, buflen1);
        if (ret != 0)
        {
            printf("发送报文失败!
    ");
        }
        //接收报文
        ret = cltSocketRev2(handle, &buf, DesDecSocket2, &len2);
        if (ret != 0)
        {
            printf("接收报文失败!
    ");
        }
    
        //释放报文内存
        if (buf != NULL)
        {
            //打印报文
            printf(buf);
            free(buf);
            buf = NULL;
        }
        //释放报文对象
        ret = cltSocketDestory(&handle);
        if (ret != 0)
        {
            printf("释放报文对象失败!
    ");
        }
    }
    
    void main(){
        ProtectB();
        system("pause");
    }
  • 相关阅读:
    验证字符串空“” 的表达式
    should not this be a private conversation
    【转】你真的了解word-wrap 和 word-break 的区别吗
    To live is to function,that is all there is in living
    [转] windows 上用程序putty使用 ssh自动登录Linux(Ubuntu)
    Vim/gvim容易忘记的快捷键
    [转] Gvim for windows中块选择的方法
    问题集
    web services
    Trouble Shooting
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5655956.html
Copyright © 2011-2022 走看看