zoukankan      html  css  js  c++  java
  • dll的在VC6.0下的使用

    [转] dll的在VC6.0下的使用 2011-6-9 18:17 阅读(0) 转载自29206390
     
     

     

     
    一、DLL的不同类型  
              使用MFC可以生成两种类型的DLL:MFC扩展DLL和常规DLL。常规DLL有可以分为动态连接和静态连接。Visual   C++还可以生成WIN32   DLL,但不是这里讨论的主要对象。  
      1、MFC扩展DLL  
            每个DLL都有某种类型的接口:变量、指针、函数、客户程序访问的类。它们的作用是让客户程序使用DLL,MFC扩展DLL可以有C++的接口。也就是它可以导出C++类给客户端。导出的函数可以使用C++/MFC数据类型做参数或返回值,导出一个类时客户端能创建类对象或者派生这个类。同时,在DLL中也可以使用DLL和MFC。  
            Visual   C++使用的MFC类库也是保存在一个DLL中,MFC扩展DLL动态连接到MFC代码库的DLL,客户程序也必须要动态连接到MFC代码库的 DLL。(这里谈到的两个DLL,一个是我们自己编写的DLL,一个装MFC类库的DLL)现在MFC代码库的DLL也存在多个版本,客户程序和扩展 DLL都必须使用相同版本的MFC代码DLL。所以为了让MFC扩展DLL能很好的工作,扩展DLL和客户程序都必须动态连接到MFC代码库DLL。而这个DLL必须在客户程序运行的计算机上。  
      2、常规DLL  
            使用MFC扩展DLL的一个问题就是DLL仅能和MFC客户程序一起工作,如果需要一个使用更广泛的DLL,最好采用常规DLL,因为它不受MFC的某些限制。常规DLL也有缺点:它不能和客户程序发送指针或MFC派生类和对象的引用。一句话就是常规DLL和客户程序的接口不能使用MFC,但在DLL和客户程序的内部还是可以使用MFC。  
            当在常规DLL的内部使用MFC代码库的DLL时,可以是动态连接/静态连接。如果是动态连接,也就是常规DLL需要的MFC代码没有构建到DLL中,这种情况有点和扩展DLL类似,在DLL运行的计算机上必须要MFC代码库的DLL。如果是静态连接,常规DLL里面已经包含了需要的MFC代码,这样 DLL的体积将比较大,但它可以在没有MFC代码库DLL的计算机上正常运行。    
      二、建立DLL  
              利用Visual   C++提供的向导功能可以很容易建立一个不完成任何实质任务的DLL,这里就不多讲了,主要的任务是如何给DLL添加功能,以及在客户程序中利用这个DLL  
      1、导出类  
            用向导建立好框架后,就可以添加需要导出类的.cpp   .h文件到DLL中来,或者用向导创建C++   Herder   File/C++   Source   File。为了能导出这个类,在类声明的时候要加“_declspec(dllexport)”,如:  
      class   _declspec(dllexport)   CMyClass  
      {  
                ...//声明  
      }  
      如果创建的MFC扩展DLL,可以使用宏:AFX_EXT_CLASS:  
      class   AFX_EXT_CLASS   CMyClass  
      {  
                ...//声明  
      }  
      这样导出类的方法是最简单的,也可以采用.def文件导出,这里暂不详谈。  
      2、导出变量、常量、对象  
            很多时候不需要导出一个类,可以让DLL导出一个变量、常量、对象,导出它们只需要进行简单的声明:_declspec(dllexport)   int   MyInt;  
          _declspec(dllexport)   extern   const   COLORREF   MyColor=RGB(0,0,0);  
          _declspec(dllexport)   CRect   rect(10,10,20,20);  
      要导出一个常量时必须使用关键字extern,否则会发生连接错误。  
      注意:如果客户程序识别这个类而且有自己的头文件,则只能导出一个类对象。如果在DLL中创建一个类,客户程序不使用头文件就无法识别这个类。  
          当导出一个对象或者变量时,载入DLL的每个客户程序都有一个自己的拷贝。也就是如果两个程序使用的是同一个DLL,一个应用程序所做的修改不会影响另一个应用程序。  
          我们在导出的时候只能导出DLL中的全局变量或对象,而不能导出局部的变量和对象,因为它们过了作用域也就不存在了,那样DLL就不能正常工作。如:  
      MyFunction()  
      {  
                  _declspec(dllexport)   int   MyInt;  
                  _declspec(dllexport)   CMyClass   object;  
      }  
      3、导出函数  
      导出函数和导出变量/对象类似,只要把_declspec(dllexport)加到函数原型开始的位置:  
      _declspec(dllexport)   int   MyFunction(int);  
      如果是常规DLL,它将和C写的程序使用,声明方式如下:  
      extern   "c"   _declspec(dllexport)   int   MyFunction(int);  
      实现:  
      extern   "c"   _declspec(dllexport)   int   MyFunction(int   x)  
      {  
                ...//操作  
      }  
      如果创建的是动态连接到MFC代码库DLL的常规DLL,则必须插入AFX_MANAGE_STATE作为导出函数的首行,因此定义如下:  
      extern   "c"   _declspec(dllexport)   int   MyFunction(int   x)  
      {  
                AFX_MANAGE_STATE(AfxGetStaticModuleState());  
                ...//操作  
      }  
      有时候为了安全起见,在每个常规DLL里都加上,也不会有任何问题,只是在静态连接的时候这个宏无效而已。这是导出函数的方法,记住只有MFC扩展DLL才能让参数和返回值使用MFC的数据类型。  
      4、导出指针  
      导出指针的方式如下:  
      _declspec(dllexport)   int   *pint;  
      _declspec(dllexport)   CMyClass   object   =   new   CMyClass;  
      如果声明的时候同时初始化了指针,就需要找到合适的地方类释放指针。在扩展DLL中有个函数DllMain()。(注意函数名中的两个l要是小写字母),可以在这个函数中处理指针:  
      #   include   "MyClass.h"  
      _declspec(dllexport)   CMyClass   *pobject   =   new   CMyClass;  
      DllMain(HINSTANCE   hInstance,DWORD   dwReason,LPVOID   lpReserved)  
      {  
              if(dwReason   ==   DLL_PROCESS_ATTACH)  
              {  
                      .....//  
              }  
              else   if(dwReason   ==   DLL_PROCESS_DETACH)  
              {  
                      delete   pobject;  
              }  
      }  
      常规DLL有一个从CWinApp派生的类对象处理DLL的开和关,可以使用类向导添加InitInstance/ExitInstance函数。  
      int   CMyDllApp::ExitInstance()  
      {  
              delete   pobject;  
              return   CWinApp::ExitInstance();  
      }  
       
      三、在客户程序中使用DLL  
              编译一个DLL时将创建两个文件.dll文件和.lib文件。首先将这两个文件复制到客户程序项目的文件夹里,这里需要注意DLL和客户程序的版本问题,尽量使用相同的版本,都使用RELEASE或者都是DEBUG版本。  
            接着就需要在客户程序中设置LIB文件,打开Project   Settings--->Link--->Object/library   Modules中输入LIB的文件名和路径。如:Debug/SampleDll.lib。除了DLL和LIB文件外,客户程序需要针对导出类、函数、对象和变量的头文件,现在进行导入添加的关键字就是:_declspec(dllimport),如:  
      _declspec(dllimport)   int   MyFunction(int);  
      _declspec(dllimport)   int   MyInt;  
      _declspec(dllimport)   CMyClass   object;  
      extern   "C"   _declspec(dllimport)   int   MyFunction(int);  
      在有的时候为了导入类,要把相应类的头文件添加到客户程序中,不同的是要修改类声明的标志:  
      class   _declspec(dllimport)   CMyClass,如果创建的是扩展DLL,两个位置都是:  
      class   AFX_EXT_CLASS   CMyClass。  

    南来地,北往的,上班的,下岗的,走过路过不要错过!

    ======================个性签名=====================

    之前认为Apple 的iOS 设计的要比 Android 稳定,我错了吗?

    下载的许多客户端程序/游戏程序,经常会Crash,是程序写的不好(内存泄漏?刚启动也会吗?)还是iOS本身的不稳定!!!

    如果在Android手机中可以简单联接到ddms,就可以查看系统log,很容易看到程序为什么出错,在iPhone中如何得知呢?试试Organizer吧,分析一下Device logs,也许有用.

    我的开发工具

    对于博客园里的网友,不敢称为叫"程序员"的人,你们攻击性太强,看来你们是不会想到我的用意的.园子里有不少人都非常喜欢Jeffrey,是因为它的第一版 框架设计 CLR via C#.
    可是从第一版到现在的第三版,没有看到真正底层的东西,内容仅仅是比MSDN文档更丰富一些,可能是我的要求太高了吧.
    也就是因为它很多时候会接触到微软开发人员,会经常聊聊某些问题而已,而它又将这些问题反应到书中.也许它就像一个小记者.
    它的年龄大我们不多,我的孩子与它小儿子一般大,如果我能向它那样出入微软与它们开发人员长时间交流,不仅仅会牛成它这样.....
    可是微软的开发人员不会扔太多时间在它这儿的.所以它会整天追着这个,赶它那个..屁颠个不停吧...
    而它的另一版被称为好书的 Windows核心编程,更是没有什么深度可言,仅仅是将windows提供的api,以及内核功能再重申了一遍.
    这些书对晋及编程知识是有些贡献的,再说一遍我不是在匾低谁,说说想法而已.

  • 相关阅读:
    格式化数字保留N位小数
    listbox美化
    501 Not Implemented:服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求。
    截透明
    CASE WHEN
    c# HttpWebRequest与HttpWebResponse 绝技
    提取网页中的超链接(C#)
    转sqlhelp
    IIS创建虚拟目录
    一次重构的过程
  • 原文地址:https://www.cnblogs.com/ioriwellings/p/15493626.html
Copyright © 2011-2022 走看看