在dll中使用
g_hBitmap = (HBITMAP)LoadImage(g_hInst, TEXT("e:\\1.bmp"), IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
其中第一个参数原来我设置为了NULL,
这样有时候就会g_hBitmap == NULL,即load失败,但是有时候会成功,后来我把dllmain中得到的hinstance传给g_hInst,就再也不出错.
我的理解是hinstance是作为dll重定位的标志的,以此为基础来计算代码位移
是这样吗?
但问题是为什么有时候又能成功的load呢?
疑惑了.

解决方案 »

  1.   

    hInstance是操作系统分配给实例的指针.程序根据hInstance访问其相应的内存空间
      

  2.   

    其实hInstance是句柄,句柄就是指针
      

  3.   

    我后来研究hook的时候发现
    如果是远程注入dll的话,那么函数的地址就是以hInstance为标准来计算的!
    所以说hInstance是重定位的标准
      

  4.   

    hInstance是操作系统分配给程序自身实例的句柄.句柄是用来标识实例的,句柄是实例指针的索引. 通过句柄能找到实例的地址.
      

  5.   

    hInstance确实是模块的基地址。VC生成的DLL的基址一般是0x10000000,exe的基址一般是0x400000。如果多个模块映射到同一基址,装载器会自动进行重定位,这会浪费一些时间,所以一般都在link的时候使用/REBASE指令改变基址。
    在exe中加载资源,搜索顺序一般是exe->扩展dll->MFC DLL。
    如果扩展dll中加载资源,搜索顺序是扩展dll->MFC DLL->exe。
    如果期望改变搜索顺序,就应该在Load资源之前,改变资源句柄:
    HINSTANCE hRes = AfxGetResourceHandle();
    AfxSetResourceHandle(::GetModuleHandle("Mydll.dll"));
    //此处加载资源,譬如LoadBitmap,LoadString,等等
    AfxSetResourceHanle(hRes);
    要注意的是,在扩展dll中,AfxGetInstanceHandle返回的是Exe的句柄而不是dll的句柄。所以此处使用::GetModuleHandle。
      

  6.   

    codewarrior(会思考的草) 
    如果多个模块映射到同一基址,装载器会自动进行重定位,这会浪费一些时间,所以一般都在link的时候使用/REBASE指令改变基址。
    用什么标准来改变基址呢?
      

  7.   

    微软提供了一个建议的标准,按你的dll的名字的首字母来分,这是它提供的表格:
    First letter Base address 
    A - C        0x60000000 
    D - F        0x61000000 
    G - I        0x62000000 
    J - L        0x63000000 
    M - O        0x64000000 
    P - R        0x65000000 
    S - U        0x66000000 
    V - X        0x67000000 
    Y - Z        0x68000000 
      

  8.   

    The base address of a DLL is the location in virtual memory where the loader attempts to place the DLL. It is generally specified at link time. If a DLL cannot load at its base address because the memory is already occupied, the loader places the DLL elsewhere in virtual memory, then updates all calls into the DLL to reflect the new base address. Making these changes can be time consuming, because the image must be copied to the pagefile and modified for the new address. If you have a large application that uses many DLLs, it is important for each DLL to have a different base address to minimize load time. 
    The system DLLs are currently based in memory from 0x70000000 to 0x78000000 (0x68000000 to 0x78000000 on MIPS). Therefore, you should base your DLLs from 0x60000000 to 0x68000000. One possible scheme is to choose a base address based on the first letter of the DLL name.
      

  9.   

    如果多个模块映射到同一基址,装载器会自动进行重定位,这会浪费一些时间,所以一般都在link的时候使用/REBASE指令改变基址。//这个/rebase指令怎么用?