VC中使用动态链接库DLL:静态调用和动态调用

VC中生成DLL的办法见:
www.codeproject.com/KB/DLL/RegDLL.aspx

--------------------------------------
VC中使用DLL
http://www.cnblogs.com/c1230v/articles/1401448.html

调用DLL有两种方法:静态调用和动态调用.
(一).静态调用其步骤如下:
1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;
2.把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;
3.把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目录下;
4.打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;
5.执行第4步后,VC将会弹出一个对话框,在对话框的多页显示控件中选择Link页。然后在Object/library modules输入框中输入:youApp.lib
6.选择你的目标工程Head Files加入:youApp.h文件;
7.最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include "youApp.h"
注:youApp是你DLL的工程名。

(二).动态调用其程序如下:
动态调用时只需做静态调用步骤1.

01  {
02      HINSTANCE  hDllInst  =  LoadLibrary( "youApp.DLL");
03      if( hDllInst)
04      {
05          typedef  DWORD ( WINAPI  * MYFUNC)( DWORD , DWORD);
06          MYFUNC  youFuntionNameAlias  =  NULL;
07         // youFuntionNameAlias 函数别名
08
          youFuntionNameAlias  = ( MYFUNC) GetProcAddress( hDllInst , "youFuntionName");
09         // youFuntionName 在DLL中声明的函数名
10          if( youFuntionNameAlias)
11          {
12              youFuntionNameAlias( param1 , param2);
13          }
14          FreeLibrary( hDllInst);
15      }
16  }


显式(静态)调用:
LIB + DLL + .H,注意.H中dllexport改为dllimport
隐式(动态)调用:
DLL + 函数原型声明,先LoadLibrary,再GetProcAddress(即找到DLL中函数的地址),不用后FreeLibrary

--------------------------------------
动态链接库DLL的链接
http://blog.donews.com/mmycly/archive/2006/06/15/917076.aspx

应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。Visual C++6.0在VC\bin目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构。另外,Windows系统将遵循下面的搜索顺序来定位DLL: 1.包含EXE文件的目录,2.进程的当前工作目录, 3.Windows系统目录, 4.Windows目录,5.列在Path环境变量中的一系列目录。

(一).隐式链接
隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用MyDll.dll库中的Min函数。首先生成一个项目为TestDll,在 DllTest.h、DllTest.cpp文件中分别输入如下代码:

01 //Dlltest.h
02
      #pragma comment(lib,"MyDll.lib")
03      extern  "C" _declspec( dllimportint  Max( int  a , int b);
04      extern  "C" _declspec( dllimportint  Min( int  a , int b);
05  //TestDll.cpp
06
  #include
07  #include"Dlltest.h"
08  void  main()
09  {
10      int  a;
11      a = min( 8 , 10)
12      printf( "比较的结果为%d \n " a);
13  }


在创建DllTest.exe文件之前,要先将MyDll.dll和MyDll.lib拷贝到当前工程所在的目录下面,也可以拷贝到windows的 System目录下。如果DLL使用的是def文件,要删除TestDll.h文件中关键字extern "C"。TestDll.h文件中的关键字Progam commit是要Visual C+的编译器在link时,链接到MyDll.lib文件,当然,开发人员也可以不使用#pragma comment(lib,"MyDll.lib")语句,而直接在工程的Setting->Link页的Object/Moduls栏填入 MyDll.lib既可。

编程时用ad.h,ad.lib,放在项目当前目录里
在头文件中加入#include "ad.h"
在Project Setting–>Link–>Object/library modules加入ad.lib
执行时将ad.dll跟你的程序放在同一目录

(二).显式链接
显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。下面是通过显式链接调用DLL中的Max函数的例子。

01  #include
02  #include
03  void  main( void)
04  {
05      typedef int( * pMax)( int  a , int b);
06      typedef int( * pMin)( int  a , int b);
07      HINSTANCE  hDLL;
08      PMax  Max
09      HDLL = LoadLibrary( "MyDll.dll"); //加载动态链接库MyDll.dll文件;
10      Max =( pMax) GetProcAddress( hDLL , "Max");
11      A = Max( 5 , 8);
12      Printf( "比较的结果为%d \n " a);
13      FreeLibrary( hDLL); //卸载MyDll.dll文件;
14
  }


在上例中使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针,然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄,然后通过GetProcAddress()函数获取导入到应用程序中的函数指针,函数调用完毕后,使用 FreeLibrary()卸载DLL文件。在编译程序之前,首先要将DLL文件拷贝到工程所在的目录或Windows系统目录下。

使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,使用GetProcAddress()函数时,可以利用 MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,"Min")改为 GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。

你可能感兴趣的:(windows,System,dll,mfc,编译器,winapi)