zoukankan      html  css  js  c++  java
  • 解决DLL和主调程序的资源冲突及如何使用Dll的资源

    工具:vs2005

       在要导出的MFC类加上AFX_EXT_CLASS,即可形成导出类.

    1.为什么引起资源冲突?

          主调程序和每个DLL都有一个全局唯一的HINSTANCE句柄(HMODULE模块),不管是在主调程序还是DLL中,加载资源都要参考HINSTANCE。主调程序和DLL都可能包含自己的资源,这些资源的ID却不是全局的,可能出现主调程序和某个DLLHINSTANCE中资源ID号相同的情况而发生加载冲突。

    2.资源冲突引起的后果?

         使用了共享的MFC库之后,默认情况下使用主程序的句柄来加载资源,所以如果DLL和主调程序的资源ID相同的话,会默认调用主调程序的资源,表现为:EXE打算调用DLL中的对话框却显示的是EXE中的对话框,本来DLL要显示a图,由于主调程序上b图的ID和a相同,则实际显示的是b图

    3.函数介绍:

         AfxGetResourceHandle:返回值:应用程序调入缺省资源的实例的HINSTANCE句柄(HMODULE模块),也就是资源所在的模块句柄,如使用的是DLL中的资源,那么就应该返回此DLL中的HINSTANCE了。在主调程序调用DLL时,返回的就是主调程序的HINSTANCE。

    4.如何让AfxGetResourceHandle返回DLL的HINSTANCE呢?

        AfxSetResourceHandle:对应于AfxGetResourceHandle,一个设置,一个获得,将DLL的HINSTANCE传入即可。

    5.如何得到DLL的HINSTANCE呢?

         Extension DLL的HINSTANCE可以从DLL的AFX_EXTENSION_MODULE结构里得到,在DLL的DllMain函数中new CDynLinkLibrary(XXXDLL);XXXDLL.hResource即为所求,不可用AfxGetInstanceHanle,它总是获得EXE模块句柄,这点要和AfxGetResourceHandle区分开。

    我们使用完DLL中的资源要使用EXE中的资源的资源怎么办呢?我们需要在使用完成后用AfxSetResource重新将资源模块的句柄设置为原来的值,如果来保证在资源使用完成后完成这一个工作呢,我们利用C++类的构造和析构机制创建了以下类来解决这个问题:


     

    在DllMain的 new CDynLinkLibrary(XXXDLL);

     加入代码 LoadDllResource::s_hDllResourceHandle = XXXDLL.hResource;

    使用方法:

    在DLL类中加入LoadDllResource类(仅加入DLL类),需要加载资源的函数起始加上 LoadDllResource autoRes;//局部变量,函数开始调用构造函数,函数结构调用析构函数

     6.如何使用动态链接库中的资源?

       个人使用的方法

    把5中的 LoadDllResource声明为导出类,比如在DLL中有资源#define IDB_BUTTON_LEFT  2004,为了使用方便,可以在主调程序的rc中同样定义#define IDB_BUTTON_LEFT  2004,在主调程序中加载DLL的资源可以用如下代码

     当然不是所有DLL都会有LoadDllResource类,所以也可以显式加载DLL

     

    7.函数介绍:

        FindResource用来在一个指定的模块中定位所指定的资源

          

     LoadResource用来将所指定的资源加载到内存当中

    LockResource用来锁定内存中的资源数据块,它的返回值也就是我们要使用的直系指向资源数据的内存指针,是lpvoid指针,也就是可以强制转换成任意需要的指针.

    另外我们还需要用SizeofResource来确定资源的尺寸,在资源使用完毕后我们不需要使用 UnlockResource和FreeResource来手动地释放资源,因为它们都是16位Windows遗留下来的,在Win32中,在使用完毕后系统会自动回收

     下面代码是借鉴过来的,详细的表现了这些函数的使用

     

    8.怎么做一个纯资源的DLL?(摘录)

     

        纯资源的DLL就是只包含资源的DLL,例如:图标,位图,字符串,声音,视频, 对话框等。使用纯资源DLL可以节约可执行文件的大小,可以被所有的应用程序 所共享,从而提高系统性能。纯资源DLL的编写比普通的DLL要简单的多,首先
    创建一个WIN32   DLL工程,不是MFC的DLL,然后创建一个资源文件*.RC,添加到资源DLL的工程中去。然后添加一个初始化DLL的原文件。
    #include  
    extern   "C "
    BOOL   WINAPI   DllMain(   HINSTANCE   hInstance,   DWORD   dwReason,   LPVOID   )
      return   1;
    这是纯资源DLL所必须需的代码,保存这个文件为*.CPP。编译这个资源DLL。 在应用程序显示的调用这个DLL,使用LoadLibrary函数装入资源 DLL,FindResource和LoadResource来装入各种资源,或者使用下列的特定的
    资源装入函数:
    FormatMessage
    LoadAccelerators
    LoadBitmap
    LoadCursor
    LoadIcon
    LoadMenu
    LoadString 
     当资源使用结束,你的应用程序须调用FreeLibrary函数来释放资源。  

    使用方法: 
        首先在应用程序中声明一个DLL的句柄,HINSTANCE   m_hLibrary;在OnCreate()函数中调用LoadLirbrary(),在OnDestory()中调用FreeLibrary()。


  • 相关阅读:
    优化SQL查询:如何写出高性能SQL语句
    提高SQL执行效率的16种方法
    Spring Ioc DI 原理
    java内存泄漏
    转:js闭包
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Best Time to Buy and Sell Stock with Cooldown
    LeetCode Length of Longest Fibonacci Subsequence
    LeetCode Divisor Game
    LeetCode Sum of Even Numbers After Queries
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693688.html
Copyright © 2011-2022 走看看