新建空项目,命名为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文件放到工程目录下面。
将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