动态库代码

//简单的动态库开发----报文发送
#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[];
//定义报文端口
char port[];
//定义报文接受数组
unsigned char * buf;
//定义报文长度
int buflen;
//定义加密函数指针变量
PDesEncSocket pe;
//定义解密函数指针变量
PDesDecSocket pd;
}SCK_HANDLE; //初始化上下文
_declspec(dllexport)
int cltSocketInit(void **handle/*out*/){
int ERRO_MSG = ;
if (handle==NULL)
{
ERRO_MSG = ;
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, , sizeof(SCK_HANDLE));
strcpy(shandle->ipaddress,"192.168.0.128");
strcpy(shandle->port, "");
*handle = shandle;
return ERRO_MSG;
} //注入加密函数指针
_declspec(dllexport)
int InjectionEnc(void *handle/*in*/, PDesEncSocket pein/*in*/){
int ERRO_MSG = ;
if (handle == NULL||pein==NULL)
{
ERRO_MSG = ;
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 = ;
if (handle == NULL || pdin == NULL)
{
ERRO_MSG = ;
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 = ;
if (handle==NULL)
{
ERRO_MSG = ;
printf("handle==NULL handle不可以为NULL erro msg :%d\n", ERRO_MSG);
return ERRO_MSG;
}
if (buf == NULL)
{
ERRO_MSG = ;
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 = ;
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 = ;
if (handle == NULL)
{
ERRO_MSG = ;
printf("handle==NULL handle不可以为NULL erro msg :%d\n", ERRO_MSG);
return ERRO_MSG;
}
if (buf == NULL)
{
ERRO_MSG = ;
printf("buf==NULL buf不可以为NULL erro msg :%d\n", ERRO_MSG);
return ERRO_MSG;
}
if (pein == NULL)
{
ERRO_MSG = ;
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 = ;
if (handle == NULL || buf == NULL || buflen==NULL)
{
ERRO_MSG = ;
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 = ;
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 = ;
return ERRO_MSG;
} //客户端收报文方式二
_declspec(dllexport)
int cltSocketRev2(void *handle/*in*/, unsigned char **buf/*out*/, PDesDecSocket pdin/*in*/, int *buflen/*in*/){
int ERRO_MSG = ;
if (handle == NULL || buf == NULL || buflen == NULL)
{
ERRO_MSG = ;
printf("handle == NULL || buf == NULL || buflen==NULL erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
if (pdin==NULL)
{
ERRO_MSG = ;
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 = ;
return ERRO_MSG;
} //客户端释放资源
_declspec(dllexport)
int cltSocketDestory(void **handle){
int ERRO_MSG = ;
if (handle==NULL)
{
ERRO_MSG = ;
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 = ;
if (plainstr == NULL || cryptstr == NULL || cryptlen == NULL)
{
ERRO_MSG = ;
printf("加密参数列表为空\n");
return ERRO_MSG;
}
//des密文比明文长,但是密文最多比明文多8个字节(所以我取10个足够)
*cryptstr = (char *)malloc((sizeof(char)*plainlen) + );
if (cryptstr == NULL)
{
ERRO_MSG = ;
printf("加密函数分配输出内存失败!\n");
return ERRO_MSG;
}
int ret = DesEnc((unsigned char *)plainstr, plainlen, (unsigned char *)*cryptstr, cryptlen);
if (ret != )
{
ERRO_MSG = ;
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 = ;
if (plainstr == NULL || cryptstr == NULL || plainlen == NULL)
{
ERRO_MSG = ;
printf("解密参数列表为空!\n");
return ERRO_MSG;
}
//分配内存空间(des密文只可能比明文长)
*plainstr = (char *)malloc((sizeof(char)*cryptlen));
if (plainstr == NULL)
{
ERRO_MSG = ;
printf("分配输出内存失败!\n");
return ERRO_MSG;
}
int ret = DesDec((unsigned char *)cryptstr, cryptlen, (unsigned char *)*plainstr, plainlen);
if (ret != )
{
ERRO_MSG = ;
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 = ;
if (plainstr == NULL || cryptstr == NULL || cryptlen == NULL)
{
ERRO_MSG = ;
printf("加密参数列表为空\n");
return ERRO_MSG;
}
//des密文比明文长,但是密文最多比明文多8个字节(所以我取10个足够)
*cryptstr = (char *)malloc((sizeof(char)*plainlen) + );
if (cryptstr == NULL)
{
ERRO_MSG = ;
printf("加密函数分配输出内存失败!\n");
return ERRO_MSG;
}
int ret = DesEnc((unsigned char *)plainstr, plainlen, (unsigned char *)*cryptstr, cryptlen);
if (ret != )
{
ERRO_MSG = ;
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 = ;
if (plainstr == NULL || cryptstr == NULL || plainlen == NULL)
{
ERRO_MSG = ;
printf("解密参数列表为空!\n");
return ERRO_MSG;
}
//分配内存空间(des密文只可能比明文长)
*plainstr = (char *)malloc((sizeof(char)*cryptlen));
if (plainstr == NULL)
{
ERRO_MSG = ;
printf("分配输出内存失败!\n");
return ERRO_MSG;
}
int ret = DesDec((unsigned char *)cryptstr, cryptlen, (unsigned char *)*plainstr, plainlen);
if (ret != )
{
ERRO_MSG = ;
printf("des解密函数执行失败!\n");
return ERRO_MSG;
}
return ERRO_MSG;
} void ProtectA(){
//定义发送报文
char str1[] = "";
//定义报文长度
int buflen1 = strlen(str1) + ;
//定义接受报文变量
char *buf = NULL;
int len2 = ;
void *handle = NULL;
int ret = ;
//初始化报文
ret = cltSocketInit(&handle);
if (ret != )
{
printf("初始化报文对象失败!\n");
}
//注入加密函数指针
ret = InjectionEnc(handle, DesEncSocket);
if (ret != )
{
printf("注入加密函数指针失败!\n");
}
//注入解密函数指针
ret = InjectionDec(handle, DesDecSocket);
if (ret != )
{
printf("注入解密函数指针失败!\n");
}
//发送报文
ret = cltSocketSend(handle, str1, buflen1);
if (ret != )
{
printf("发送报文失败!\n");
}
//接收报文
ret = cltSocketRev(handle, &buf, &len2);
if (ret != )
{
printf("接收报文失败!\n");
} //释放报文内存
if (buf != NULL)
{
//打印报文
printf(buf);
free(buf);
buf = NULL;
}
//释放报文对象
ret = cltSocketDestory(&handle);
if (ret != )
{
printf("释放报文对象失败!\n");
}
} void ProtectB(){
//定义发送报文
char str1[] = "";
//定义报文长度
int buflen1 = strlen(str1) + ;
//定义接受报文变量
char *buf = NULL;
int len2 = ;
void *handle = NULL;
int ret = ;
//初始化报文
ret = cltSocketInit(&handle);
if (ret != )
{
printf("初始化报文对象失败!\n");
}
//发送报文
ret = cltSocketSend2(handle, str1, DesEncSocket2, buflen1);
if (ret != )
{
printf("发送报文失败!\n");
}
//接收报文
ret = cltSocketRev2(handle, &buf, DesDecSocket2, &len2);
if (ret != )
{
printf("接收报文失败!\n");
} //释放报文内存
if (buf != NULL)
{
//打印报文
printf(buf);
free(buf);
buf = NULL;
}
//释放报文对象
ret = cltSocketDestory(&handle);
if (ret != )
{
printf("释放报文对象失败!\n");
}
} void main(){
ProtectB();
system("pause");
}

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

  1. C语言:判断字符串是否为回文,-函数fun将单向链表结点数据域为偶数的值累加起来。-用函数指针指向要调用的函数,并进行调用。

    //函数fun功能:用函数指针指向要调用的函数,并进行调用. #include <stdio.h> double f1(double x) { return x*x; } double f ...

  2. C语言函数指针(转载)

    二.通常的函数调用 一个通常的函数调用的例子:/* 自行包含头文件 */void MyFun(int x); /* 此处的声明也可写成:void MyFun(int) */int main(int a ...

  3. C语言函数指针 和 OC-Block

    C语言函数指针 和 OC-Block 一. C语言函数指针 关于函数指针的知识详细可参考:http://www.cnblogs.com/mjios/archive/2013/03/19/2967037 ...

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

    本文转自:http://www.cnblogs.com/windlaughing/archive/2013/04/10/3012012.html 示例1: void myFun(int x); //声 ...

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

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  6. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  7. “对外部(局部)变量的访问”是C语言函数指针的最大弱点

    1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...

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

    //函数指针做函数参数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<Wi ...

  9. 深入理解C语言-函数指针

    函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...

随机推荐

  1. Ubuntu12.04 Bugzilla 和 TestOpia的安装步骤

    1.        安装apache User@ubuntu:$  sudo apt-get install apache2 注:安装完以后能够通过http://192.168.128.128/ 来訪 ...

  2. ACE中静态实例管理方式

    ACE中的很多类使用了单例模式,为了便于管理单例对象,ACE使用了一个组件——ACE_Framework_Component来专门管理. 我们以ACE_Reactor这个单例类的创建和释放为例. 1. ...

  3. 一学就会之ado.net(一)

    ado.net十一组用于和数据源进行交互的面向对象类库.数据源能够是数据库也能够是文本文件.excel表格或者XML文件. 简单来说.ado.net就是与不同的数据源进行交互(增删改查)的. ado. ...

  4. 【VBA编程】09.使用Excle集合对象

    使用Workbooks工作簿集合.工作簿对象.工作表集合.工作表对象,并且观察使用Add方法前后工作簿与工作表数目的变化 [代码区域] Sub 测试集合工作簿() Dim wbs As Workboo ...

  5. servlet 简单filter避免中文乱码等

    Filter是个servlet中的接口,servlet内部实现了利用Filter来过滤请求.   可以在filter中根据条件决定是否调用chain.doFilter(request,response ...

  6. Drupal中的模块载入

    什么是模块载入?首先说载入,这里的载入是指require_once.模块载入就是指require_once模块目录中的某个PHP文件. 每个Drupal模块都应该有自己的主文件.模块主文件以模块名开始 ...

  7. resin设置jvm参数

    http://www.quiee.com.cn/archives/592/ resin resin3.0 及前期版本内存设置, 如下: 启动时设置虚拟内存: unix> bin/httpd.sh ...

  8. [机器学习实战] 决策树ID3算法

    1. 决策树特点: 1)优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据. 2)缺点:可能会产生过度匹配问题. 3)适用数据类型:数值型和标称型. 2. 一般流程: ...

  9. kettle--组件(1)--值映射

    组件:值映射 如下如所示: 首先,给出官方给出的文档: 个人理解: Target field name:可以理解为将source column的字段复制为另一个target column的名字. De ...

  10. Office 365 离线安装

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yueque.blog.51cto.com/4580340/1707479 有个O ...