有,rocks_lee(石子儿),我想知道证据

解决方案 »

  1.   

    转贴:
     
      Belle    原作  什么是“句柄”(handle),handle的本意是把柄,把手的意思。是你与操作系统打交道的东东。举个通俗的例子,比如你考上了大学,入学后,学校(操作系统)会给你一个学生证号。注意,这个号码是学校指定的,你无法自选。有了这个号码(学生证,假设一证多用)享受学校提供的服务:如你就可以去图书馆借书,去食堂吃饭,去教室上课等等。但你不能到食堂里买啤酒,因为学校不允许这种服务。而在计算机中系统提供的服务就是API调用,你有了HANDLE,就可以理直气壮地向系统提出调用API的服务。而指针的权力就大多了,有了指针你可以到处去喝酒,打架,学校(操作系统)管不着,所以句柄和指针的区别在于句柄指针调用系统提供的服务。而句柄虽然是一个能相互区别的号码,但与我们普通的ID号又有区别,普通的ID号是可以由程序员自己定义的,而句柄不行,它是对象生成是系统指定的,是为了区别系统中存在的各个对象,这个句柄不是由程序员符给的。  句柄 
        1。句柄,是整个windows编程的基础,一个句柄是指使用的一个唯一的整数值,是指一个四字节长的数值,用于标志应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息。
        2。句柄不是一个指针,程序不能利用它句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。
        3。句柄是windows用来标志应用程序中建立的或是使用的唯一整数,windows使用了大量的句柄来来标志很多对象。http://www.csdn.net/develop/article/10/10284.shtm
      

  2.   

    Belle的那篇文章就是经典的M$瞎话^o^下面注意听我的证据:
    请先到Windef.h找绝大多数句柄的定义:
    DECLARE_HANDLE(HWND);
    DECLARE_HANDLE(HHOOK);
    ……
    DECLARE_HANDLE(HGDIOBJ);
    DECLARE_HANDLE(HBITMAP);
    DECLARE_HANDLE(HBRUSH);
    ……
    typedef HANDLE              HGLOBAL;
    typedef HANDLE              HLOCAL;
    ……OK, 现在大家跟我一起翻到Winnt.h,看看DECLARE_HANDLE和HANDLE到底是什么:
    #ifdef STRICT
    typedef void *HANDLE;
    #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
    #else
    typedef PVOID HANDLE;
    #define DECLARE_HANDLE(name) typedef HANDLE name
    #endif
    typedef HANDLE *PHANDLE;哈哈,现在知道了吧,HANDLE就是PVOID,也就是无类型指针,
    而DECLARE_HANDLE(HWND);就是:
    struct HWND__ {
         int unused;};
    typedef struct HWND__ *HWND;
    现在实际上都清楚啦,这些Handles都不过是指向struct的指针,至于这个struct的用处,连M$都说unused了,^o^现在解释下M$这么做的意义,这就是所谓数据封装,你可以在你的程序中把M$的内部结构指针传来传去,可是你却不知道它到底指向的内容是什么,而且可以编个句柄的瞎话防止大家的质疑:)。而M$的程序大可以这么写:
    #include <windows.h>  //这个和大家用的一样
    #include "windows_in.h"  //这个是M$自用的,外人别想看到^o^HSOMETHINGELSE DoSomething(HSOMETHING hSomething) {
        struct RealSomething* p = (struct RealSomething*)hSomething; //先强制类型转换成内部结构指针
        ……do something……
        return (HSOMETHINGELSE)pRealSomethingElse;//强制类型逆转换
    }^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  ^o^  
      

  3.   

    哈哈
    明明是对的,生说是错的
    核心编程里早说过了,它指的是个未知用途的结构;
    把它当作句柄,是因为你不可能根据这个“指针”找到对应的对象,但OS能;
    所以不管它是怎么来的,它都只是个ID,而且是个进程内的ID,其他进程不能直接引用,想引用就得转换;
    你说它要是“指针”,干嘛还要转换?
      

  4.   

    就好比:
          学校======process
          学生======object
          学号======handle
    你知道一个A学校(A process)的学生甲(object甲),有他的学号(handle甲)然后你用email把这个学号(handle甲)发给了B学校(B process)B学校(B process)按学号(handle甲)找到的可能是学生乙((handle乙),或者没找到因为A学校(A process)与B学校(B process)中,这个学号可能是都有的,也可能不是这就需要给高一层的系统来解释(实际当然不一样了,人嘛)
      

  5.   

    前面的分析很经典,但我认为有一点必须指出的。如果不对,请各位指证。
    句柄是指针,一点不假,但是这个指针又与C中的指针有不同之处。因为Windows是一个我任务的系统,其内存是可以移动的,这样的话如果某一时刻有一个指针指向一块内存,之后的某个时刻却被系统移走了,如果你再用这个指针的话就会出错。为了解决这一问题,windows在系统专区开一块内存用于存放句柄,这个句柄的值就是一个地址,当这一块内存被移走后,windows就修改这个句柄的值,再访问这块内存时,句柄的值总是有效的。正因为这样当你使用GlobalAlloc分配的内存时,如果你指定这块内存的属性是固定的,那么它的返回值可以直接给一个指针,如果是可以移动的,返回值就必须给一个句柄,你就必须先GlobalLock后才能使用。
    这是我对句柄理解,不知道对不对?
      

  6.   

    前面的可以做个实验
    把你的应用程序句柄强制类型转换一下:
    (PIMAGE_DOS_HEADER)hInstance
    看看是不是一个标准的Dos header, 
    然后(PIMAGE_NT_HEADERS32)((BYTE*)hInstance+((PIMAGE_DOS_HEADER)hInstance)->e_lfanew)
    看看是不是一个标准的PE header以上证明HINSTANCE(HMODULE)其实是可执行文件内存映射的首地址。正确的结论应该是,绝大多数句柄都是指针。
      

  7.   

    前面的可以做个实验
    把你的应用程序句柄强制类型转换一下:
    (PIMAGE_DOS_HEADER)hInstance
    看看是不是一个标准的Dos header, 
    然后(PIMAGE_NT_HEADERS32)((BYTE*)hInstance+((PIMAGE_DOS_HEADER)hInstance)->e_lfanew)
    看看是不是一个标准的PE header以上证明HINSTANCE(HMODULE)其实是可执行文件内存映射的首地址。正确的结论应该是,绝大多数句柄都是指针。   
      

  8.   

    rocks_lee(石子儿)is right !! Handle is a pointer!
      

  9.   

    是在win2000下做的实验吗?
    那么说核心的作者jeffry在骗人?
    呵呵
    实在懒的做,等你的结果了,认真的说
      

  10.   

    我当然是做过实验的, 5分钟不就搞定了?指针是什么? 是内存这个大数组的一个索引而已, 知道一个索引并不意味着你就可以知道索引所指内容的含义, OS当然知道, 因为OS是M$编的.
    正确的结论应该是,绝大多数句柄都是指针. 这意味着, 有些句柄不是指针^_^