Day7(下).动态库开发基础
来源:互联网 发布:魔兽网络代理 编辑:程序博客网 时间:2024/06/06 23:36
动态库开发是我们学习C/C++过程中,首先最接近工作实战的项目,在实现动态库的开发前,我们需要先进行动态库开发环境的搭建。
以下是动态库开发环境搭建的步骤图,按先后顺序排序:
执行完上面的步骤以后,可以编译看看,有的编译器会出错,有的会编译通过,我的VS2013可以通过。
我们以socket通信的实例说明,首先添加以下框架代码
#include "stdlib.h"#include "stdio.h"#include "string.h"//第一套api接口//客户端初始化 获取handle上下文int cltSocketInit(void **handle){return 0;}//客户端发报文int cltSocketSend(void *handle, unsigned char *buf, int buflen){return 0;}//客户端收报文int cltSocketRev(void *handle, unsigned char * buf, int *buflen){return 0;}//客户端释放资源int cltSocketDestroy(void *handle){return 0;}
虽然我们定义了四个函数,但是这样我们仍然无法被外部使用,必须在这四个函数之前加上_declspec(dllexport)。这句话的意思是说,这个函数是动态库往外面抛出的函数,并且注意,必须在每个函数前面加上!!都添加完成以后,F7编译,在主目录Debug文件夹下就会生成相应的dll动态库文件和lib文件,需要说明的是,.lib文件是描述动态库中哪几个函数抛出来了。
为了使用这两个dll和lib文件,我们创建另一个工程,取名“动态库调用测试案例”,并把dll和lib文件复制到此案例工程主目录下。然后如下图
测试案例工程添加头文件socketclientdll.h和demo_动态库调用测试.c源文件,代码如下
socketclientdll.h
//socketclientdll.h/*下面定义了一套socket客户端发送报文接受报文的api接口请写出这套接口api的调用方法*/#ifndef _INC_Demo01_H#define _INC_Demo01_H#ifdef __cplusplusextern "C" {#endif//------------------第一套api接口---Begin--------------------------------////客户端初始化 获取handle 上下文信息int cltSocketInit(void **handle /*out*/); //客户端发报文int cltSocketSend(void *handle /*in*/, unsigned char *buf /*in*/, int buflen /*in*/);//客户端收报文int cltSocketRev(void *handle /*in*/, unsigned char *buf /*in*/, int *buflen /*in out*/);//客户端释放资源int cltSocketDestory(void *handle/*in*/);//------------------第一套api接口---End-----------------------------------////------------------第二套api接口---Begin--------------------------------//int cltSocketInit2(void **handle); //客户端发报文int cltSocketSend2(void *handle, unsigned char *buf, int buflen);//客户端收报文int cltSocketRev2(void *handle, unsigned char **buf, int *buflen);int cltSocketRev2_Free(unsigned char **buf);//客户端释放资源int cltSocketDestory2(void **handle);//------------------第二套api接口---End--------------------------------//#ifdef __cplusplus}#endif#endif /* _INC_Demo01_H */demo_动态库调用测试.c
//demo_动态库调用测试.c#define _CRT_SECURE_NO_WARNINGS#include "stdlib.h"#include "stdio.h"#include "string.h"#include "socketclientdll.h"void main(){int ret = 0;void*handle = NULL;unsigned char buf[128];int buflen = 11; /*in*/unsigned char outbuf[128];int outbufLen; /*in*/strcpy(buf, "adddddddddddddddddddddddaaaaaaaa");ret = cltSocketInit(&handle /*out*/);if (ret != 0){printf("cltSocketInit err:%d", ret);goto End;}//客户端发报文ret = cltSocketSend(handle /*in*/, buf /*in*/, buflen /*in*/);if (ret != 0){printf("func cltSocketSend() err:%d", ret);goto End;}//客户端收报文//底层库提供的是一种机制, 而不是具体的策略ret = cltSocketRev(handle /*in*/, outbuf, &outbufLen);if (ret != 0){printf("func cltSocketSend() err:%d", ret);goto End;}printf("outbuf: %s \n", outbuf);End://客户端释放资源if (handle != NULL){cltSocketDestory(handle/*in*/);}system("pause");}
这样,初期的动态库开发环境已经搭建成功。下面我们继续底层链接库文件的具体功能的开发。
首先我们实现socketclientwmb.c文件中第一个主函数的实现
//socketclientwmb.c#define _CRT_SECURE_NO_WARNINGS#include "stdlib.h"#include "stdio.h"#include "string.h"typedef struct _SCK_HANDLE{char version[16];char serverip[16];int serverport;}SCK_HANDLE;//第一套api接口//客户端初始化 获取handle上下文_declspec(dllexport)int cltSocketInit(void **handle){int ret = 0;SCK_HANDLE *sh = NULL;sh = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));if (sh == NULL){ret = -1;printf("func cltSocketInit() err:%d", ret);return ret;}strcpy(sh->version, "1.0.0");strcpy(sh->serverip, "192.168.0.100");sh->serverport = 8080;*handle = sh;return ret;}****************以下省略****************
接下来我们编写第二个函数体
//客户端发报文_declspec(dllexport)int cltSocketSend(void *handle, unsigned char *buf, int buflen){int ret = 0;SCK_HANDLE *sh = NULL;if (handle == NULL || buf == NULL || buflen > 3323214324){ret = -1;printf("func cltSocketSend() err:%d", ret);return ret;}sh = (SCK_HANDLE *)handle;sh->pbuf = (char *)malloc(buflen * sizeof(char));if (sh->pbuf == NULL){ret = -2;printf("func cltSocketSend() malloc err, buflen:%d", buflen);return ret;}memcpy(sh->pbuf, buf, buflen);sh->buflen = buflen;return 0;}下面是第三个函数体
//客户端收报文_declspec(dllexport)int cltSocketRev(void *handle, unsigned char * buf, int *buflen){int ret = 0;SCK_HANDLE *sh = NULL;if (handle == NULL || buf == NULL || buflen == NULL){ret = -1;printf("func cltSocketRev() err:%d", ret);return ret;}sh = (SCK_HANDLE *)handle;memcpy(buf, sh->pbuf, sh->buflen);*buflen = sh->buflen;return ret;}最后是释放资源的函数体
//客户端释放资源_declspec(dllexport)int cltSocketDestroy(void *handle){int ret = 0;SCK_HANDLE *sh = NULL;if (handle == NULL){ret = -1;printf("func cltSocketDestroy() err:%d", ret);return ret;}sh = (SCK_HANDLE *)handle;if (sh->pbuf != NULL){free(sh->pbuf);}free(sh);return ret;}
这样整个代码就完成了。
0 0
- Day7(下).动态库开发基础
- day7下
- Django基础,Day7
- php基础学习day7(接口和错误处理)
- Python廖雪峰实战web开发(Day7-编写MVC)
- Python3教程Web开发实战梳理-day7(编写MVC)
- 传智播客-Java基础加强-day7
- linux下c语言-day7
- day1-day7 开发环境准备
- 面向对象(day7)
- Day7
- DAY7
- day7
- DAY7
- Day7
- day7
- day7
- day7
- 第十三周项目1-动物这样叫(1)
- 学习笔记《C#入门经典(第6版)》C#语言:第3章
- 数据结构——直接插入排序(c++)
- 【Codeforces61E】Enemy is weak
- 第1章 概述
- Day7(下).动态库开发基础
- 【华为oj】输入一行字符,分别统计,英文字符,空格字符,数字字符,和其他字符的个数
- HDOJ 1113 Word Amalgamation
- javax.xml.registry.infomodel.User
- C#:DataTable映射成Model
- 《程序员面试宝典》(第三版)笔记整理
- HDFS分布式系统
- 数据结构——直接选择排序(c++)
- Spring MVC基本原理