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
原创粉丝点击