如何建立及链接动态链接库。

什么是 DLL?

DLL 是一个包含可由多个程序同时使用的代码和数据的库。例如,在 Windows 操作系统中,Comdlg32 DLL 执行与对话框有关的常见函数。因此,每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框。这有助于促进代码重用和内存的有效使用。

通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。例如,一个计帐程序可以按模块来销售。可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。

此外,可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。例如,您可能具有一个工资计算程序,而税率每年都会更改。当这些更改被隔离到 DLL 中以后,您无需重新生成或安装整个程序就可以应用更新。

下表说明了 Windows 操作系统中的一些作为 DLL 实现的文件:
ActiveX 控件 (.ocx) 文件
ActiveX 控件的一个示例是日历控件,它使您可以从日历中选择日期。
控制面板 (.cpl) 文件
.cpl 文件的一个示例是位于控制面板中的项。每个项都是一个专用 DLL。
设备驱动程序 (.drv) 文件
设备驱动程序的一个示例是控制打印到打印机的打印机驱动程序。

DLL 的优点

下表说明了当程序使用 DLL 时提供的一些优点:
使用较少的资源
当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。
推广模块式体系结构
DLL 有助于促进模块式程序的开发。这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
简化部署和安装
当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。
DLL 帮助数据库
DLL 帮助数据库帮助您查找由 Microsoft 软件产品安装的特定版本的 DLL。有关 DLL 帮助数据库的更多信息,请访问下面的 Microsoft 网站:

DLL 开发

本节介绍您在开发自己的 DLL 时应该考虑的问题和要求。
DLL 的类型
当您在应用程序中加载 DLL 时,可以使用两种链接方法来调用导出的 DLL 函数。这两种链接方法是加载时动态链接和运行时动态链接。
加载时动态链接
在加载时动态链接中,应用程序像调用本地函数一样对导出的 DLL 函数进行显式调用。要使用加载时动态链接,请在编译和链接应用程序时提供头文件 (.h) 和导入库文件 (.lib)。当您这样做时,链接器将向系统提供加载 DLL 所需的信息,并在加载时解析导出的 DLL 函数的位置。
运行时动态链接
在运行时动态链接中,应用程序调用 LoadLibrary 函数或 LoadLibraryEx 函数以在运行时加载 DLL。成功加载 DLL 后,可以使用 GetProcAddress 函数获得要调用的导出的 DLL 函数的地址。在使用运行时动态链接时,无需使用导入库文件。

下面的列表说明了有关何时使用加载时动态链接以及何时使用运行时动态链接的应用程序条件:
启动性能
如果应用程序的初始启动性能很重要,则应使用运行时动态链接。
易用性
在加载时动态链接中,导出的 DLL 函数类似于本地函数。这使您可以方便地调用这些函数。
应用程序逻辑
在运行时动态链接中,应用程序可以分支,以便按照需要加载不同的模块。在开发多语言版本时,这一点很重要。

 

示例 DLL 和应用程序

在 Microsoft Visual C++ 6.0 中,可以通过选择“Win32 动态链接库”项目类型或“MFC 应用程序向导 (dll)”来创建 DLL。
下面的代码是一个“Win32 应用程序”项目的示例,该示例调用 SampleDLL DLL 中的导出 DLL 函数。

在运行时动态链接中,您应使用与以下代码类似的代码来调用 SampleDLL.dll 导出 DLL 函数。
当您编译和链接 SampleDLL 应用程序时,Windows 操作系统将按照以下顺序在下列位置中搜索 SampleDLL DLL:

1.应用程序文件夹
2.当前文件夹
3.Windows 系统文件夹

注意GetSystemDirectory 函数返回 Windows 系统文件夹的路径。
4.Windows 文件夹

注意GetWindowsDirectory 函数返回 Windows 文件夹的路径。

// SampleDLL.cpp
//

#include "stdafx.h"
#define EXPORTING_DLL
#include "sampleDLL.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

void HelloWorld()
{
	MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}
// File: SampleDLL.h
//
#ifndef INDLL_H
#define INDLL_H

#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld() ;
#else
extern __declspec(dllimport) void HelloWorld() ;
#endif

#endif
//main.cpp
#include <windows.h>
typedef void(*DLLPROC)();//一定要注意这个的定义方法啊。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR pchCmdLine, int iCmdShow )
{
 HINSTANCE hinstDLL;
 DLLPROC HelloWorld;
 BOOL fFreeDLL;
 hinstDLL = LoadLibrary("sampleDLL.dll");
 if (hinstDLL != NULL)
 {
  HelloWorld = (DLLPROC)GetProcAddress(hinstDLL, "HelloWorld");
  if (HelloWorld != NULL){
   HelloWorld();
  }
  fFreeDLL = FreeLibrary(hinstDLL);
 }
 return 0;
}
 
  
  

 再提供一个简单的例子吧。

/* 文件名:lib.h */

#ifndef LIB_H
#define LIB_H
extern "C" int __declspec(dllexport)add(int x, int y);
#endif

/* 文件名:lib.cpp */

#include "lib.h"
int add(int x, int y)
{
 return x + y;
}

/*main.cpp*/

#include <stdio.h>
#include <windows.h>

typedef  int(*lpAddFun)(int, int); //宏定义函数指针类型
int main(int argc, char *argv[])
{
 HINSTANCE hDll; //DLL句柄
 lpAddFun addFun; //函数指针
 hDll = LoadLibrary("..//Debug//dllTest.dll");
 if (hDll != NULL)
 {
  addFun = (lpAddFun)GetProcAddress(hDll, "add");
  if (addFun != NULL)
  {
   int result = addFun(2, 3);
   printf("%d", result);
  }
  FreeLibrary(hDll);
 }
 return 0;
}


 

 dll文件也可以这样写:


#ifndef _cplusplus

#define EXPORT extern "C" __declspec(dllexport)
#else
#define EXPORT __declspec(dllexport)

#endif

EXPORT void DllFoo(void) ;// 有的程序这个地方设为了EXPORT void CALLBACK DllFoo(void);但是我用着是不好使。还是慎用为好。


还有一种连接的方法:

以VS2003为例:[项目]→[属性]→[链接]→[输入]→里面设定为./usb.def (这个文件和DLL主函数同一目录下)

usb.def文件里面这样写:

------------------------

DESCRIPTION "usb dll"

EXPORTS

Open  @1
Close  @2
------------------------

把DLL文件里面的函数都写在上面就好了。

然后重新编译DLL工程,在Debug文件夹里面就会出现usb.dll和usb.lib两个文件。

把usb.lib文件加载到应用程序里面,usb.dll文件可以拷贝到应用程序主函数目录下,或者是直接拷贝到C:/WINDOWS/system32下,都可以。这样的话,在应用程序里面,就可以访问DLL里面的函数了。当然,在应用程序的头文件里一定要声明你要用到的函数才行。

祝大家好运!~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值