dll动态库调用,js调用dll动态链接库

  dll动态库调用,js调用dll动态链接库

  一.动态链接库简介

  它是动态链接库的缩写。DLL是一个包含代码和数据的库,可以被多个程序同时使用。DLL不是可执行文件。动态链接为进程提供了一种调用不属于其可执行代码的函数的方式。函数的可执行代码位于一个DLL中,该DLL包含一个或多个函数,这些函数与使用它们的进程分开编译、链接和存储。dll也有助于共享数据和资源。多个应用程序可以同时访问内存中单个DLL副本的内容。DLL是一个包含代码和数据的库,可以被多个程序同时使用。例如,在Windows操作系统中,Comdlg32 DLL执行与对话框相关的常见功能。因此,每个程序都可以使用这个DLL中包含的函数来实现“打开”对话框。这有助于促进代码重用和内存的有效使用。

  通过使用DLL,程序可以模块化,由相对独立的组件组成。例如,会计程序可以按模块出售。每个模块都可以在运行时加载到主程序中(如果安装了相应的模块)。由于模块之间相互独立,程序的加载速度更快,只有在请求相应的功能时才加载模块。

  此外,在不影响程序其他部分的情况下,将更新应用到每个模块也更容易。例如,您可能有一个工资计算程序,税率每年都在变化。在DLL中隔离这些更改后,您可以应用更新,而无需重新构建或安装整个程序。

  与动态链接库相对应的,还有一个函数库,叫做静态链接库。两者的主要区别在于用法。

  静态链接库是将(lib)文件中使用的函数代码直接链接到目标程序中,程序运行时不需要其他库文件;动态链接是指将被调用函数所在的文件模块(DLL)和被调用函数在文件中的位置等信息链接到目标程序中。程序运行时,从DLL中查找相应的函数代码,因此需要相应DLL文件的支持。

  静态链接库和动态链接库都是共享代码的方式。如果采用静态链接库,那么不管你喜不喜欢,lib中的所有指令都会直接包含在最终的EXE文件中。但是,如果使用DLL,它不需要包含在最终的EXE文件中。EXE文件执行时,可以“动态”引用并卸载这个独立于EXE的DLL文件。静态链接库和动态链接库的另一个区别是,静态链接库不能再包含其他动态链接库或静态库,而动态链接库还可以包含其他动态或静态链接库。

  "每个lib文件都是几个函数的定义(假设只有函数)"

  lib库有两种,一种叫导出库,包含函数所在的DLL文件和文件中函数位置的信息;一种是包含功能代码本身。通常,现有的DLL使用前一个库。

  有静态库和动态库。

  静态lib将导出声明和实现都放在lib中。编译后,所有代码都嵌入到宿主程序中。

  动态lib相当于一个H文件,是实现部分导出部分的声明(。dll文件)。编译后,导出声明只是部分编译到宿主程序中,运行时需要相应的dll文件支持。

  通过#include包含这些函数声明的头文件后,我们的应用程序可以使用lib文件中的函数

  下面分析DLL的优缺点省略一千多字。有兴趣的话百度一下。

  根据DLL是否使用MFC,分为普通Win32 DLL和基于MFC的DLL两种。DLL一般有以下三个文件:包含文件、导入库文件和实际代码文件,它们对应的扩展名是。h,lib和。DLL。

  看看下面的例子,一步一步来。

  二、开发常见的Win32 DLL

  此win32 DLL示例仅实现了一个简单的DLL,该DLL包含一个比较整数数组并返回最大数的函数。

  (1)对于新项目,默认可以选择其他选项。按下“确定”按钮后,直接单击向导中的“完成”按钮。

  (2)添加DLL的函数文件

  根据DLL的介绍,DLL开发编译时会生成三个文件,分别是包含文件、导入库文件和实际代码文件,它们对应的扩展名分别是。h,lib和。DLL。

  所以我们开发的第一步是生成头文件,这个头文件包含了导出的内容,另外两个文件会在导出的时候自动生成。将头文件添加到项目中,并包含要导出的函数int Max(int[],int)。

  然后编写Max的实现代码,同样创建一个新的Max.cpp文件并包含在项目中,如下图所示:

  至此,我们的DLL函数实现文件已经完成。接下来,我们将导出这个函数。

  (3)衍生函数

  这一步我们需要开发的DLL有哪些内容需要导出。DLL中导出的内容可以包括函数、类和各种资源等。导出内容有两种方式:一种是在定义这些导出内容时使用export关键字_declspec(dllexport),另一种是添加模块定义文件。定义到DLL项目。注意:这两种方法不能同时使用,只能选择其中一种。

  我们以这个项目为例,看看如何通过以上两种方法导出内容。

  l使用export关键字_declspec(dllexport)

  //sort . h —— dll的头文件(包含要导出的内容)

  extern C _ declspec(dll export)void Max(int[],int);

  我们可以相应地扩展它,我们可以使用这个关键字导出类中的所有公共成员变量和函数成员,比如:

  class _ declspec(dll export)my class

  {

  myclass类中的所有公共成员变量和函数成员都成为导出内容。

  }

  使用模块定义文件。极好的

  在项目文件夹中添加一个文本文件,名为Win32DLLExample。DEF,然后将以下内容添加到该文件中:

  库Win32DLLExample

  描述“实现一个简单的Win32DLL”

  出口

  最大@1

  下面是对DEF文件内容的简单分析:

  DEF的第一条语句必须是库语句,标识DEF文件属于哪个DLL,后面是DLL的名称(此处为Win32DLLExample)。

  第二条语句是DLL用法描述语句,没有实际作用,可以省略。

  第三条语句EXPORTS是DEF文件的核心,用于列出导出的内容。EXPORTS允许对函数进行编号(从1到n),在数字前面加一个@符号,可以省略。

  l在这个例子中,我们选择使用export关键字_declspec(dllexport)来导出函数Max():

  (4)创建DLL和LIB文件

  前面的工作完成后,直接点击build,在项目调试文件夹中生成DLL和LIB文件。

  到目前为止,我们已经完成了这个简单Win32 DLL的开发。让我们看看如何使用我们开发的这个DLL。

  第三,使用常见的Win32 DLL

  使用DLL有两种方式:隐式链接和显示链接。因为隐式链接不能真正体现DLL的灵活性,所以隐式链接是在应用程序加载时将DLL加载到内存中。当应用程序使用多个DLL时,隐式链接占用系统资源,而显示链接在需要时将DLL加载到内存中,在不需要时释放,节省系统资源,提高效率。

  本例中我们使用显示链接,windows提供了三个显示链接使用DLL的API函数:一是调用LoadLibrary函数加载DLL,二是调用GetProcAddress获取并使用函数在DLL中的第一个地址,三是调用FreeLibrary函数卸载DLL。具体用法见示例代码。

  (1)创建应用程序。

  首先,创建一个名为UseWin32DLL的控制台应用程序。

  (2)添加包含文件和DLL,将Win32DLLExample项目中的max.h文件和Win32DLLExample复制到新项目UseWin32DLL目录下,然后通过项目-添加到项目-文件菜单将sort.h添加到项目UseWin32DLL中。此时导出的内容(相对于原DLL项目)变成了导入的内容(相对于使用该DLL的程序),所以max.h中的all _declspec(dllexport)应该改为_declspec(dllimport)。

  修改后的max.h文件如下:

  (3)编辑应用程序

  添加一个包含项目主函数的C源文件。源文件的内容如下:

  (4)构建应用程序来检查结果。

  截图如下:

  结果正常。

  注意:

  当我们把开发的程序复制到其他目录或者其他机器上时,需要把DLL和程序一起打包放在同一个目录下,或者其他正确的目录下(当前exe目录-windows系统目录-windows目录-环境变量Path中指定的一系列目录)。上面的括号是exe搜索dll的目录顺序。当这些目录中没有所需的DLL时,程序将报告一个错误,表明DLL加载失败,程序将自动退出。

  看了Win32 DLL的开发,应该没什么难度。我怎样才能得到一个DLL并使用它?关键是我们知道它提供给我们使用的功能、资源等导出内容是什么,我们知道这些内容的用处。一般情况下,DLL会提供一个指令文档以供参考。再来看看基于MFC的DLL开发,功能更强大。

  四。MFC DLL开发

  MFC DLL可以使用MFC类库,从而在MFC下开发更强大的模块。基于MFC的dll有三种类型:静态链接的MFC dll、动态链接的MFC dll和扩展的MFC dll,它们是常用的。它们支持C接口,即DLL可以导出其中定义的类,而另外两个MFC DLL不能导出其他模块的MFC派生类,这也是扩展MFC DLL的优势。我们可以从MFC类库中派生出自己的类,然后导出类,这样更强大。

  我们举一个简单的例子,看看如何开发和使用基于MFC的DLL,其中DLL类型是扩展的MFC DLL。

  1.创建MFC DLL项目

  有图有真相,请看下图,话我就不说了。

  在这里,直接按Finish按钮来完成新项目。

  2.添加包含的文件。

  在这一步中,我们向项目添加一个Date类,并选择Insert-New Class;为简单起见,在弹出的新建类对话框中,类类型,我们选择泛型类,新建一个普通类,如下图所示:

  单击OK完成类的创建。

  3.编辑导出的内容。

  类相对简单。为了更好的了解各种资源的导出以及在应用中的使用情况,有三类导出内容:一是菜单资源,二是日期类,三是导出函数。

  改进我们的Date类,Date.h文件的代码如下:

  //Date 1 . h:Date类的接口。

  //

  //////////////////////////////////////////////////////////////////////

  #如果!已定义(AFX _ date 1 _ H _ _ 8d 209 c73 _ DEED _ 4B9F _ BA73 _ 435d 30 da 0 a9 a _ _ INCLUDED _)

  # define AFX _ date 1 _ H _ _ 8d 209 c73 _ DEED _ 4B9F _ BA73 _ 435d 30 da 0 a9 a _ _ INCLUDED _

  # VER国际机场1000

  #杂注一次

  #endif //_MSC_VER 1000

  //定义菜单资源

  #定义IDR_MENU_MAIN 5000

  #定义IDR_MENU_SHOW 5001

  //定义导出类

  class AFX_EXT_CLASS日期

  {

  公共:

  date();

  虚拟~ Date();

  公共:

  void SetYear(int num);

  void SetMonth(int num);

  void SetDay(int num);

  int GetYear();

  int GetMonth();

  int GetDay();

  CString GetDate();

  私人:

  int年;

  int月;

  int日;

  };

  //定义导出函数

  extern C AFX_EXT_API Max(int,int);

  #endif //!已定义(AFX _ date 1 _ H _ _ 8d 209 c73 _ DEED _ 4B9F _ BA73 _ 435d 30 da 0 a9 a _ _ INCLUDED _)

  Date.cpp实现文件的代码如下:

  //Date 1 . CPP:Date类的实现。

  //

  //////////////////////////////////////////////////////////////////////

  #include stdafx.h

  #包含“日期1.h”

  #ifdef _DEBUG

  #undef THIS_FILE

  static char THIS _ FILE[]=_ _ FILE _ _;

  #定义新的DEBUG_NEW

  #endif

  //////////////////////////////////////////////////////////////////////

  //建设/破坏

  //////////////////////////////////////////////////////////////////////

  日期:日期()

  {

  日=0;

  月=0;

  年份=0;

  }

  日期:~日期()

  {

  }

  无效日期:SetDay(int num)

  {

  日=数;

  }

  无效日期:SetMonth(int num)

  {

  month=num

  }

  无效日期:SetYear(int num)

  {

  year=num

  }

  int Date:GetDay()

  {

  返回日;

  }

  int Date:GetMonth()

  {

  返回月份;

  }

  int Date:GetYear()

  {

  返回年份;

  }

  CString Date:GetDate()

  {

  字符串日期;

  约会。格式( %d年%d月%d日,年,月,日);

  返回日期;

  }

  int Max(int a,int b)

  {

  回个b?甲:乙;

  }

  在上面的代码中,我们使用了MFC定义的两个宏AFX_EXT_CLASS和AFX_EXT_API,它们的定义是:

  #ifdef _AFXEXT

  # define AFX _ EXT _ CALSS _ declspec(dll export)

  # define AFX _ EXT _ API _ declspec(dll export)

  #否则

  # define AFX _ EXT _ CALSS _ declspec(dllimport)

  # define AFX _ EXT _ API _ declspec(dllimport)

  #endif

  现在我们在资源编辑器中插入菜单:

  由于我们在Date类中定义的菜单的两个ID名称不同于系统默认ID,我们需要如下更改菜单的ID:

  同样,我们预定义的菜单ID值是5000和5001,而系统默认ID值一般都不一样,所以我们要修改系统默认ID值。具体方法是:打开resource.h文件,找到我们预定义的两个宏:

  修改上图中两个选定宏的值,如下所示:

  好了,我们所做的工作就是生成DLL和Lib文件。记得检查编译项目的调试文件中是否有扩展名为DLL和LIB的文件:

  动词(verb的缩写)使用MFC DLL

  在上面的例子中,我们已经生成了自己的扩展MFC DLL。现在我们通过使用这个DLL来熟悉一下MFC DLL的用法。

  1.基于对话框创建一个新的MFC应用程序,命名为UseMFCDLL,这里就不说怎么生成了。

  2.添加文件

  复制MFCDLLExample.DLL,MFCDLLExample。将上面开发的DLL项目文件夹中的LIB和Date.h文件添加到当前项目UseMFCDLL文件夹中,将Date.h添加到项目中,设置项目的Link属性(项目-设置-链接属性页),将MFCDLLExample.lib添加到项目中。

  3.接下来,我们将DLL中定义的菜单资源添加到对话框中。

  在UseMFCDLLDlg.cpp文件中添加文件包含语句:# include "date.h "

  修改UseMFCDLLDlg.cpp文件中的OnInitDialog()函数,如下所示:

  4.因为我们使用的是DLL中的菜单资源,所以不能在ClassWizard中直接为菜单项IDR_MENU_SHOW命令添加相应的函数,需要手动添加,如下:

  (1)在对话框的头文件中添加命令映射函数语句afx _ msg OnCommandShowDate();

  (2)在对话框实现文件中添加消息映射:

  (3)然后,将响应IDR_MENU_SHOW命令的函数OnCommandShowDate()的实现写入对话框实现文件中。我们在其中使用了DLL中定义的Date类,代码如下:

  void CUseMFCDLLDlg:OnCommandShowDate()

  {

  日期日期;

  约会。SetDay(27);

  约会。SetMonth(Max(3,4));

  约会。SetYear(2010年);

  AfxMessageBox(日期。GetDate());

  }

  运行结果如下:

  一切都如我们所料。

  备注:

  上述两个示例的演示代码可以从下载:

  win32 dll:http://download..net/source/2290658

  MFC DLL:http://download..net/source/2290696

  出发地:http://blog..net/sllins/article/details/5533764

dll动态库调用,js调用dll动态链接库