调用DLL的步骤

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

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

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

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

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

在开发调试阶段,每次对DLL工程的更新以后,一定要将新的.lib 文件和 .dll文件重新拷贝到外部应用程序的目录下。

简述一下win32环境的DLL:

1、编写win32程序下的DLL工程,并生成解决方案,在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"

typedef struct SCK_HANDLE
{
	char version[64];
	char ip[128];
	int port;
	char *p;      //结构体套一级指针,注意内存的释放问题
	int plen;
}SCK_HANDLE;//动态库过程内部的数据类型,不想让外部上层应用测试程序
//数据类型的封装

//------------------第一套API接口---Begin--------------------------------//

//客户端初始化——获取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-----------------------------------//

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-23 03:51:16

调用DLL的步骤的相关文章

Qt调用dll中的功能函数

DLL 优点 ------------------------------------- 1.扩展了应用程序的特性: 2.可以用许多种编程语言来编写: 3.简化了软件项目的管理: 4.有助于节省内存: 5.有助于资源共享: 6.有助于应用程序的本地化: 7.有助于解决平台差异: 8.可以用于一些特殊的目的.windows使得某些特性只能为DLL所用. 转载:http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810239.html Qt调用d

Qt调用DLL

声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下: void HelloWorld();     //函数内部调用Win32 API,功能是弹出一个helloworld提示框   int add(int a,int b);  //实现两个数相加,并返回结果 下面分别通过显示调用和隐式调用两种方法,来模拟Qt如何调用外部dll文件中的功能函数,follo

php调用dll经验小结

最近做一个网站,需要频繁使用远程数据,数据接口已经做好.在做转换的时候遇到了性能上的问题:开始打算用php来实现转换,苦苦查了数天,都没有找到直接操作字节的方法.虽然可以使用 pack() 方法将各个数据压入结构中,但是在解压的时候却不能通过 unpack() 简单的解出来,需要通过 //php code for( $i = 0; $i < $length; $i+=2 ){ $tempstr = $tempstr.chr( hexdec(substr($array["data"

c++/c语言中如何调用DLL

参考网站如下: ?http://blog.csdn.net/yusongwhu/article/details/7577461 http://www.cnblogs.com/lhbssc/archive/2012/02/08/2342853.html 具体内容如下: (1)篇? 今天在研究怎么在vc中调用动态dll的问题,看了一个下午,总算有些眉目. 首先来说说调用的原理: 调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同

SQLSERVER调用DLL程序

在SQL Server中调用dll分为两个步骤 1.创建一个dll文件(dll文件分成3种类型,讲其中一种) 2.把dll文件放进SQL Server的程序集中.然后定义一个Function,就可以通过该Function来引用dll中的函数. 1创建一个dll文件 1.1点击“文件”->“新建”->“项目”->类库,把命名空间改成TestDLL,添加如下代码 (框架必须改为.NET3.5及3.5以下,因为SQL Server 2008只是支持.NET 3.5及一下,.NET 4.0是20

QT直接调用dll

Qt调用DLL方法 直接调用DLL则需要三个文件,头文件(.h).导入库文件(.lib).动态链接库(.dll),具体步骤如下: 注意:在qtCreaor中生成的动态库库文件文件为.a结尾,vs生成的动态链接库是.lib结尾 1.首先我们把 .h与.lib/.a 文件复制到程序当前目录下,然后再把dll文件复制到程序的输出目录(如果是debug版的话就将mydlld.dll放在此文件夹下,Release相同).(注意:如果dll是用C写的,因此要用 extern "C" { #incl

java中调用dll文件的两种方法

一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676   JNative地址:http://www.jb51.net/article/35232.htm JNA方法: 介绍 给大家介绍一个最新的访问本机代码的Java框架—JNA. JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架

在VS2012中采用C++中调用DLL中的函数 (4)

这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人Blog在C++中调用DLL中的函数(1)(2)(3) 但是问题出现了,上面讲述的步骤很详细但是在自己运行的时候却会出现错误,于是今天在使用google“vs2012 c++调用dll”时,发现了一篇MSDN上的指南:http://msdn.microsoft.com/zh-cn/library/m

Java-JNA调用DLL(转)

源:JNA调用DLL 介绍 给大家介绍一个最新的访问本机代码的Java框架—JNA. JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架. JNA项目地址:https://jna.dev.java.net/ 非常强大.易用,功能上类似与.NET的P/Invoke. 不堪回首的JNI 我们知道,使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的. 如果有一个现有的.dll/.so文件,如果使用JNI技