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\n", 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\n", 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\n", 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\n", ERRO_MSG);
        return ERRO_MSG;
    }
    if (buf == NULL)
    {
        ERRO_MSG = 2;
        printf("buf==NULL buf不可以为NULL erro msg :%d\n", 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\n", 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\n", ERRO_MSG);
        return ERRO_MSG;
    }
    if (buf == NULL)
    {
        ERRO_MSG = 2;
        printf("buf==NULL buf不可以为NULL erro msg :%d\n", ERRO_MSG);
        return ERRO_MSG;
    }
    if (pein == NULL)
    {
        ERRO_MSG = 4;
        printf("pein==NULL 传入参数函数指针不可以为空 erro msg :%d\n", 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\n", ERRO_MSG);
        return ERRO_MSG;
    }
    //定义临时上下文变量
    SCK_HANDLE *sh = NULL;
    sh = (SCK_HANDLE *)handle;
    //不需要分配返回报文的内存,这里有解密函数分配
    if (sh->pd==NULL)
    {
        ERRO_MSG = 2;
        printf("解密函数指针为空  erro msg:%d\n", 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\n", ERRO_MSG);
        return ERRO_MSG;
    }
    if (pdin==NULL)
    {
        ERRO_MSG = 2;
        printf("pdin == NULL  msg:%d\n", 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\n", 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("加密参数列表为空\n");
        return ERRO_MSG;
    }
    //des密文比明文长,但是密文最多比明文多8个字节(所以我取10个足够)
    *cryptstr = (char *)malloc((sizeof(char)*plainlen) + 10);
    if (cryptstr == NULL)
    {
        ERRO_MSG = 2;
        printf("加密函数分配输出内存失败!\n");
        return ERRO_MSG;
    }
    int ret = DesEnc((unsigned char *)plainstr, plainlen, (unsigned char *)*cryptstr, cryptlen);
    if (ret != 0)
    {
        ERRO_MSG = 3;
        printf("des加密函数执行失败!\n");
        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("解密参数列表为空!\n");
        return ERRO_MSG;
    }
    //分配内存空间(des密文只可能比明文长)
    *plainstr = (char *)malloc((sizeof(char)*cryptlen));
    if (plainstr == NULL)
    {
        ERRO_MSG = 2;
        printf("分配输出内存失败!\n");
        return ERRO_MSG;
    }
    int ret = DesDec((unsigned char *)cryptstr, cryptlen, (unsigned char *)*plainstr, plainlen);
    if (ret != 0)
    {
        ERRO_MSG = 3;
        printf("des解密函数执行失败!\n");
        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("加密参数列表为空\n");
        return ERRO_MSG;
    }
    //des密文比明文长,但是密文最多比明文多8个字节(所以我取10个足够)
    *cryptstr = (char *)malloc((sizeof(char)*plainlen) + 10);
    if (cryptstr == NULL)
    {
        ERRO_MSG = 2;
        printf("加密函数分配输出内存失败!\n");
        return ERRO_MSG;
    }
    int ret = DesEnc((unsigned char *)plainstr, plainlen, (unsigned char *)*cryptstr, cryptlen);
    if (ret != 0)
    {
        ERRO_MSG = 3;
        printf("des加密函数执行失败!\n");
        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("解密参数列表为空!\n");
        return ERRO_MSG;
    }
    //分配内存空间(des密文只可能比明文长)
    *plainstr = (char *)malloc((sizeof(char)*cryptlen));
    if (plainstr == NULL)
    {
        ERRO_MSG = 2;
        printf("分配输出内存失败!\n");
        return ERRO_MSG;
    }
    int ret = DesDec((unsigned char *)cryptstr, cryptlen, (unsigned char *)*plainstr, plainlen);
    if (ret != 0)
    {
        ERRO_MSG = 3;
        printf("des解密函数执行失败!\n");
        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("初始化报文对象失败!\n");
    }
    //注入加密函数指针
    ret = InjectionEnc(handle, DesEncSocket);
    if (ret != 0)
    {
        printf("注入加密函数指针失败!\n");
    }
    //注入解密函数指针
    ret = InjectionDec(handle, DesDecSocket);
    if (ret != 0)
    {
        printf("注入解密函数指针失败!\n");
    }
    //发送报文
    ret = cltSocketSend(handle, str1, buflen1);
    if (ret != 0)
    {
        printf("发送报文失败!\n");
    }
    //接收报文
    ret = cltSocketRev(handle, &buf, &len2);
    if (ret != 0)
    {
        printf("接收报文失败!\n");
    }

    //释放报文内存
    if (buf != NULL)
    {
        //打印报文
        printf(buf);
        free(buf);
        buf = NULL;
    }
    //释放报文对象
    ret = cltSocketDestory(&handle);
    if (ret != 0)
    {
        printf("释放报文对象失败!\n");
    }
}

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("初始化报文对象失败!\n");
    }
    //发送报文
    ret = cltSocketSend2(handle, str1, DesEncSocket2, buflen1);
    if (ret != 0)
    {
        printf("发送报文失败!\n");
    }
    //接收报文
    ret = cltSocketRev2(handle, &buf, DesDecSocket2, &len2);
    if (ret != 0)
    {
        printf("接收报文失败!\n");
    }

    //释放报文内存
    if (buf != NULL)
    {
        //打印报文
        printf(buf);
        free(buf);
        buf = NULL;
    }
    //释放报文对象
    ret = cltSocketDestory(&handle);
    if (ret != 0)
    {
        printf("释放报文对象失败!\n");
    }
}

void main(){
    ProtectB();
    system("pause");
}
时间: 2024-10-15 01:02:42

C语言 函数指针三(反向调用)的相关文章

深入理解C语言函数指针(转)

本文转自:http://www.cnblogs.com/windlaughing/archive/2013/04/10/3012012.html 示例1: void myFun(int x); //声明也可写成:void myFun( int ); int main() { myFun(100);//一般的函数调用 return 0; } void myFun(int x) { printf("myFun: %d\n",x); } 我们一开始只是从功能上或者说从数学意义上理解myFun

C#委托与C语言函数指针及函数指针数组

C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用的时候通过指针访问这个函数. 在C语言中函数指针的申明如下: //可以理解为申明一个指着变量 Func ,它的类型是 返回Type(可以为 void )类型的参数,接收 (Type one,Type two,...)类型的//参数(可以不接受参数). Type *Func(Type one,Type

C语言 函数指针的应用

简单的介绍下C语言函数指针的用法. 函数指针的声明: char (* FunPtr)(char); 或者char (* FunPtr)(char ch);  (声明类型个形参类型根据实际情况更改) 例: 1 #include"stdio.h" 2 3 char myFun(char ch) 4 { 5 printf("myFun is called, your char is %c.\n",ch); 6 return 'w'; 7 } 8 9 void main()

c语言函数指针实例

如果使用typedef 是这样的 //可以把一个小写字母变成大写 //char (*pFun)(char); typedef char (*PTRFUN)(char); PTRFUN pFun; char glFun(char a){ return a & 223;} void print(int a,PTRFUN call){ cout<<call(a)<<endl;}void main() { pFun = glFun; print('a',pFun);} 如果不使用t

c语言函数指针

1 void PrePrintOrTree(struct TreeNode* root, void (*WorkPrint)(double)){ 2     struct TreeNode* index = root; 3     if (root == NULL){ 4         return; 5     } 6     PrePrintOrTree(root->lchild,WorkPrint); 7     (*WorkPrint)(root->value); 8     Pre

Python Cookbook(第3版)中文版:15.12 将函数指针转换为可调用对象

15.12 将函数指针转换为可调用对象? 问题? 你已经获得了一个被编译函数的内存地址,想将它转换成一个Python可调用对象,这样的话你就可以将它作为一个扩展函数使用了. 解决方案? ctypes 模块可被用来创建包装任意内存地址的Python可调用对象.下面的例子演示了怎样获取C函数的原始.底层地址,以及如何将其转换为一个可调用对象: >>> import ctypes >>> lib = ctypes.cdll.LoadLibrary(None) >>

C语言 函数指针二(正向调用)

//函数指针做函数参数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<Windows.h> /* 函数指针做函数参数 实现了2大功能:1.定义了一个指针类型,分配了4个字节大小的内存空间 2.规定了调用函数的参数列表,和返回值 正向调用:通过window自带系统函数库调用dll文件,获取dll文件中的函数地址,执行函数 反向调用:通过函数指针,在另一个函数里调用别的函数 */

C语言 函数指针定义三种方式

//函数指针 #include<stdio.h> #include<stdlib.h> #include<string.h> //函数指针类型跟数组类型非常相似 //函数名就是函数的地址,函数的指针,对函数名进行&取地址操作,还是函数名本身,这是C语言编译器的特殊处理 void test(int a){ printf("a=%d\n",a); } void ProtectA(){ //定义函数类型 typedef void(FunType)(

深入浅出剖析C语言函数指针与回调函数(一)【转】

本文转载自:http://blog.csdn.net/morixinguan/article/details/65494239 关于静态库和动态库的使用和制作方法. http://blog.csdn.NET/morixinguan/article/details/52451612 今天我们要搞明白的一个概念叫回调函数. 什么是回调函数? 百度的权威解释如下: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说