博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编写、调用DLL的步骤
阅读量:4124 次
发布时间:2019-05-25

本文共 3481 字,大约阅读时间需要 11 分钟。

       比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。其中可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。 

  Windows系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种 方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Microsoft Windows自己就将一些主要的系统功能以DLL模块的形式实现。例如IE中的一些基本功能就是由DLL文件实现的,它可以被其它应用程序调用和集成。

        底层库提供的是一种机制,而不是满足某一个人的策略。

   一般来说,DLL是一种磁盘文件(通常带有DLL扩展名),它由全局数据、服务函数和资源组成(说白了,就是一堆功能函数,有的是为了自己需要,有的是需要提供给外部使用——_declspec(dllexport)抛出去),在运行时被系统加载到进程的虚拟空间中,成为调用进程的 一部分。如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。Windows 在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。

编写动态链接库文件时,不要有中文!动态链接库工程其实就是一套API函数(可以被外部程序使用)的集成!

动态库工程会提供让函数导出来以便其他应用、工程使用的机制。在DLL代码中,必须像下面这样明确声明导出函数:_declspec(dllexport) int MyFunction(int n);

在开发调试阶段,每次对DLL工程的更新以后,一定要将新的.lib 文件和 .dll文件重新拷贝到外部应用程序的目录下。为了方便别人使用,使使用者对dll中的函数一目了然,还要编写一个.h文件,注明要抛出来的函数。

简述一下win32环境的DLL:

Debug对应Debug版本,Release对应Release版本,一定要注意版本、路径、配置动态库等对应。

1、编写win32程序下的DLL工程(注意:添加新项目一定要添加的是.c文件),并生成解决方案,在debug目录下找到如下文件并拷贝:

#include"stdio.h"#include"stdlib.h"_declspec(dllexport)int add(int a, int b){	return a + b;}
2、另外新建项目,编写测试DLL工程:
#include"stdio.h"#include"stdlib.h"void main(){	printf("%d\n", add(5, 3));}
把上述拷贝的文件粘贴在
以上.c文件的同级目录下。

3、右键测试工程——属性——连接器——输入——

注意:填的是.lib文件的全名,不是.dll的全名。

一个较为复杂的socketdll.c展示:(里面含有很多其他的技术细节)

#define  _CRT_SECURE_NO_WARNINGS #include"stdlib.h"#include"string.h"#include"stdio.h"//理解handle句柄(底层动态库的一套资源)的概念typedef struct SCK_HANDLE{	char version[64];	char ip[128];	int port;	char *p;      //结构体套一级指针,注意内存的释放问题	int plen;}SCK_HANDLE;//动态库过程内部的数据类型,不想让(也不需要)外部上层应用测试程序使用//数据类型的封装//------------------第一套API接口---Begin--------------------------------////客户端初始化——获取handle——handle是底层库的资源,记录着函数运行的上下文信息_declspec(dllexport)int cltSocketInit(void **handle /*out*/){	printf("cltSocketInit begin\n");	int ret = 0;	SCK_HANDLE  *phandle=NULL;    //SCX_HANDLE是动态库工程的变量,所以要用malloc,要在堆上分配	phandle = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));	if (phandle == NULL)	{		printf("func cltSocketInit err:%d\n",ret);		return ret;	}	memset(phandle, 0, sizeof(SCK_HANDLE));    //把指针所指向的内存空间 赋值成 0;	strcpy(phandle->ip, "192.168.1.128");	phandle->port = 8081;	*handle = phandle;   //间接赋值,把形参甩出去	printf("cltSocketInit end\n");	return 0;}//客户端发报文_declspec(dllexport)int cltSocketSend(void *handle /*in*/, unsigned char *buf /*in*/, int buflen /*in*/){	int ret = 0;	SCK_HANDLE *phandle = NULL;	phandle = (SCK_HANDLE *)handle;	phandle->p = (char *)malloc(buflen*sizeof(char));	if (phandle == NULL)	{		ret = -1;		printf("cltSocketSend err:%d\n", ret);		return ret;	}	memcpy(phandle->p, buf, buflen);  //别人传过来的有可能不是C风格的字符串,所以按内存块拷贝	phandle->plen = buflen;		return 0;}//客户端收报文_declspec(dllexport)int cltSocketRev(void *handle /*in*/, unsigned char *buf /*in*/, int *buflen /*in out*/){	int ret = 0;	SCK_HANDLE *phandle = NULL;	phandle = (SCK_HANDLE *)handle;	memcpy(buf, phandle->p, phandle->plen);    //别人传过来的有可能不是C风格的字符串,所以按内存块拷贝	buflen = phandle->plen;	return 0;}//客户端释放资源_declspec(dllexport)int cltSocketDestory(void *handle/*in*/){	int		ret = 0;	SCK_HANDLE  *hdl = NULL;	hdl = (SCK_HANDLE *)handle;	if (hdl->p)   //先释放结构体 成员域的 指针 所指向的内存空间	{		free(hdl->p);	}	free(hdl);  //再释放整个结构体内存	return 0;}//------------------第一套api接口---End-----------------------------------//
底层库分配的资源,一定要调用底层库的释放资源函数来释放资源,不要在主函数中简单的释放。

你可能感兴趣的文章
新工作的第4天
查看>>
Product Investigation on Saturday
查看>>
Ideas from Software Process Training
查看>>
Another day
查看>>
First Impression Written Down
查看>>
This One-one Meeting
查看>>
If your Commute Card unavailable?
查看>>
Decided to take test
查看>>
About today’s daily meeting
查看>>
It’s not what I wanted
查看>>
郁可维最棒
查看>>
All of coincidence
查看>>
SQL SERVER和ORACLE 的TimeZone问题
查看>>
工程,工艺
查看>>
大对象,小对象
查看>>
自上而下,自下而上
查看>>
你认为Agile为什么会如此受欢迎?
查看>>
Allow Batch in ADO.NET
查看>>
应不应该使用存储过程的几个要点
查看>>
社会价值观的多元化
查看>>