c++总结系列(-)----动态库(dll)

(-)动态链接库与静态链接库的区别:
 第一:静态链接库种的指令包含在可执行文件中(exe),动态链接库不会
 第二:静态链接库中不能包含其他动态或静态库,动态链接库可以。
           其他主要区别:dll(动态链接库)的编制与具体的编程语言以及编译器无关,   visual                           basic,visial      c++,delphi都可以使用他

(二)关于静态库:静态库(lib)的调用需要头文件(#include ".h")和添加库文件(.lib),添加库文件可以利用开发环境添加,也可以代码添加:#pragma comment(lib,"lib//tlib.lib")

   例如:

 /*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<iostream.h>
 #include "lib//add.h"
 #pragma comment(lib,"lib//tlib.lib")
 void main()
 {
  
  cout<<"juhua"<<add(1,2);
 }

       
  (三) dll的分类:
               非mfc库:不采用c++类库结构,能被非mfc和mfc编写的应用程序调用
               mfc库:包含一个继承自CWinApp的类,但无消息循环。
               mfc扩展dll:只能被mfc类库所编写的应用程序所调用

  (四)动态库(dll)的使用

    /*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 <windows.h>
 #include <iostream.h>
 typedef int (*lpAddFun)(int,int);
 void main()
 {
   HINSTANCE hDll;
   lpAddFun addFun;
   hDll = LoadLibrary("..//debug//dlib.dll");
   if(hDll!=NULL)
   {
    addFun = (lpAddFun)GetProcAddress(hDll,"add");
    if(addFun!=NULL)
    {
     int result = addFun(2,3);
     cout<<result;
    }
    FreeLibrary(hDll);
   }
  
 }
 
 其中__declsec(dllexport) 表明该函数是导出函数,应用程序可以调用他,还有一种
 内部函数,只在dll中使用他 

(五)声明dll导出函数


  DLL中导出函数的声明有两种方式:一种为4.1节例子中给出的在函数声明中加上__declspec(dllexport),这里不再举例说明;另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。

  下面的代码演示了怎样同.def文件将函数add声明为DLL导出函数(需在dllTest工程中添加lib.def文件):
 ; lib.def : 导出DLL函数
 
 LIBRARY dllTest
 
 EXPORTS
 
 add @ 1
 
 .def文件的规则为:
 
   (1)LIBRARY语句说明.def文件相应的DLL;
 
   (2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);
 
   (3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行。
 
   由此可以看出,例子中lib.def文件的含义为生成名为“dllTest”的动态链接库,导出其中的add函数,并指定add函数的序号为1。

 (六) dll库的静态调用方式:
 由编译系统完成对dll的加载和应用程序结束时的卸载。当调用某dll的应用程序结束时
 若系统还用其他应用程序使用该dll,则windows对dll的应用记录减一,直到所有使用该dll
 的程序都结束时才释放他。
 //其中dlib.dll 需要与可执行文件放在一起。
 /*main.cpp*/
 #include <windows.h>
 #include <iostream.h>
 #pragma  comment(lib,"..//debug//dlib.lib")
 extern "C" __declspec(dllexport) add(int x,int y);
 
 void main()
 {
     cout<<add(2,3);
 }

(七)dll的变量调用方式

 ;author juhua
 ;file : lib.def
 LIBRARY DLIB
 EXPORTS
 add @ 1
 globalVar DATA
 
 /*lib.h*/
 #ifndef LIB_H
 #define LIB_H
 
 extern int globalVar;
 extern "C" int __declspec(dllexport)add(int x,int y);
           
 
 #endif
 
 
 /*lib.cpp*/
 #include "lib.h"
 #include "windows.h"
 #include <iostream.h>
 
 
 int globalVar=78;
 
 
 int add(int x,int y)
 {
  return x+y;
 }
 
 BOOL APIENTRY DllMain(HANDLE Hmodle, DWORD ul_reason_for_call, LPVOID lpReserved)
 {
  switch(ul_reason_for_call) {
  case DLL_PROCESS_ATTACH:cout<<"process attach"<<endl;
   break;
  case DLL_THREAD_ATTACH:cout<<"thread attach"<<endl;
   break;
  case DLL_THREAD_DETACH:cout<<"thread detach"<<endl;
   break;
  case DLL_PROCESS_DETACH:cout<<"process detach"<<endl;
   break;
 
  }
  return true;
 }

 /*main.cpp*/
 #include <windows.h>
 #include <iostream.h>
 #pragma comment(lib,"..//debug//dlib.lib")
 //extern int __declspec(dllexport) globalVar;
 extern int globalVar;
 void main()
 {
 
 }

(八) dll中类的导出
      //文件名:point.h,point类的声明
 
 #ifndef POINT_H
 
 #define POINT_H
 
 #ifdef DLL_FILE
 
 class _declspec(dllexport) point //导出类point
 
 #else
 
 class _declspec(dllimport) point //导入类point
 
 #endif
 
 {
  
 public:
  
  float y;
  
  float x;
  
  point();
  
  point(float x_coordinate, float y_coordinate);
  
 };
 
 #endif

  //文件名:point.cpp,point类的实现
 
 #ifndef DLL_FILE
 
 #define DLL_FILE
 
 #endif
 
 #include "point.h"
 
 //类point的缺省构造函数
 
 point::point()
 
 {
 
 x = 0.0;
 
 y = 0.0;
 
 }
 
 //类point的构造函数
 
 point::point(float x_coordinate, float y_coordinate)
 
 {
 
 x = x_coordinate;
 
 y = y_coordinate;
 
 }
 

      /*main.cpp*/
       #include "../circle.h"   //包含类声明头文件,注意没有定义DLL_FILE

 #pragma comment(lib,"dllTest.lib");


 int main(int argc, char *argv[])

 {
 
 circle c;
 
 point p(2.0, 2.0);
 
 c.SetCentre(p);
 
 c.SetRadius(1.0);
 
 printf("area:%f girth:%f", c.GetArea(), c.GetGirth());
 
 
 return 0;
 
 }

阅读更多

没有更多推荐了,返回首页