天天看點

句柄——描述符

    經常遇到“句柄”一詞,也知道他就是某個辨別符。我的了解就是,像IP位址一樣,它用一個統一的辨別規則表示可能有某些相同操作或性質的一類事物。就像IP位址可以掩蓋該系統的硬體軟體一樣,不同的資源,如檔案、程序等等。

    查了一些資料,他們的基本上局限在windows上,或更加具體的實在MFC上。其實,我查找句柄的含義是因為在Linux下也有句柄的概念,覺得應該好好了解一下。

handle的漢語解釋是柄、把手、把柄,

金山詞霸内對handle一詞的解釋如下:

handle

[5hAndl]

n.

柄, 把手, 把柄, 口實, 手感

vt.

觸摸, 運用, 買賣, 處理, 操作

vi.

搬運, 易于操縱

n.

[計]句柄

handle

han.dle

AHD:[h²n“dl]

D.J.[6h#ndl]

K.K.[6h#ndl]

v.(動詞)

han.dled, han.dling, han.dles

v.tr.(及物動詞)

To touch, lift, or hold with the hands.

用雙手觸摸、舉起或握住

To operate with the hands; manipulate.

用手操作;操縱

To deal with or have responsibility for; conduct:

處理或負責;管理:

handles matters of corporate law.

處理公司法的事物

To cope with or dispose of:

對付或處理:

handles problems efficiently.

有效地處理問題

To direct, execute, or dispose of:

訓示,實行,處理:

handle an investment.

進行一項投資

To manage, administer to, or represent:

管理,支配,代表:

handle a boxer.

給拳擊手作經紀人

To deal or trade in the purchase or sale of:

經營買賣、經銷:

a branch office that handles grain exports.

經營谷物出口的一家分公司

v.intr.(不及物動詞)

To act or function in a given way while in operation:

操作,操控:操作時以指定的方式行動:

a car that handles well in the snow; a boat that handles poorly in rough water.

在雪地裡易于駕駛的車子;在急流中難以操控的船

n.(名詞)

A part that is designed to be held or operated with the hand.

把手:設計用來由手握住或操縱的部位

An opportunity or a means for achieving a purpose.

可乘之機:實作目的的機會或方式

Slang A person's name.

【俚語】 名稱,頭銜:一個人的名字

Games The total amount of money bet on an event or over a set period of time.

【遊戲】 賭注:在一次或一段固定的時間内的用來打賭的錢的總數

get a handle on或

have a handle on 【非正式用語】

To achieve an understanding of:

了解,明白:

I was finally able to get a handle on the true nature of the problem.

最終我能夠了解這個問題的實質

Middle English handelen

中古英語 handelen

from Old English handlian

源自 古英語 handlian

han“dleless

adj.(形容詞)

handle, manipulate, wield, ply

These verbs mean to use or operate with or as if with the hands.

這些動詞的意思是用或好象用手操作。

Handle  applies widely and suggests competence:

Handle  這個詞應用廣泛而且暗示了能力:

He handles an ax like a born woodsman.

他使起斧子就象是一個天生在森林中居住的人。

She handled the employee's problem with sensitivity and direction.

她憑直覺處理雇工問題。

Manipulate  connotes skillful or artful management,as of a tool or an instrument:

Manipulate  顯示出技巧性和處理問題的藝術性,例如一件工具或儀器:

The radio operator manipulated the dials and changed the frequency. When manipulate  refers to people or personal affairs,  it often implies deviousness or the use of improper influence or fraud in gaining an end:

無線員操作排程表盤,轉換頻率。 當manipulate 指人或私人事物時, 它經常暗示用不光明正大或借助不正确的影響或欺詐行為以獲得結果:

I put forth his suggestion as my own without realizing I had been manipulated.

我把他的意見作為我自己的提了出來,絲毫沒有意識到我被利用了。

Wield  implies freedom, skill, and ease in handling physical or figurative tools and implements:

Wield  暗示在操縱一些實際的或象征性的工具或儀器時的揮灑自如、技巧和随意:

wield a hatchet;

揮動一柄戰斧;

wields a persuasive pen. It also connotes effectiveness in the exercise of intangibles such as authority or influence:

運用具說服力的筆杆子。 它還意味着其中有諸如權威和影響等不可捉摸的東西的效力:

wielded enormous power.

行使極大的權力。

Ply  suggests industry and persistence, as in the use of tools (

Ply  暗示在諸如使用工具時的勤奮和堅持不懈(

plying a knife and fork with gusto);  the term also applies to the regular and diligent engagement in a task or pursuit (

以極大的熱情起勁地揮舞着刀和叉); 這個詞還意味着經常性地、勤奮地從事某項任務或活動(

plies the baker's trade). See also Synonyms at  touch, treat

勤奮經營烤面包業) 參見同義詞 touch, treat

handle

hand 手+ -le 字尾

handle

carry ondeal indirectfeelfingergovernmanagemanipulateregulateruntouchtrade inuse

從上述解釋我們可以看出,handle其實就是某個東西,通過該東西我們可以操縱一個資源,或者說句柄是該資源的一個描述符,而且是系統中唯一的。下面轉載其它解釋,大同小異。

什麼是句柄 時間:2004-08-10

http://blog.xjtu.edu.cn/user1/505/archives/2005/17886.shtml

所謂句柄實際上是一個資料,是一個Long (整長型)的資料。

句柄是WONDOWS用來辨別被應用程式所建立或使用的對象的唯一整數,WINDOWS使用各種各樣的句柄辨別諸如應用程式執行個體,視窗,控制,位圖,GDI對象等等。WINDOWS句柄有點象C語言中的檔案句柄。

從 上面的定義中的我們可以看到,句柄是一個辨別符,是拿來辨別對象或者項目的,它就象我們的姓名一樣,每個人都會有一個,不同的人的姓名不一樣,但是,也可 能有一個名字和你一樣的人。從資料類型上來看它隻是一個16位的無符号整數。應用程式幾乎總是通過調用一個WINDOWS函數來獲得一個句柄,之後其他的 WINDOWS函數就可以使用該句柄,以引用相應的對象。

如果想更透徹一點地認識句柄,我可以告訴大家,句柄是一種指向指針的指針。我 們知道,所謂指針是一種記憶體位址。應用程式啟動後,組成這個程式的各對象是住留在記憶體的。如果簡單地了解,似乎我們隻要獲知這個記憶體的首位址,那麼就可以 随時用這個位址通路對象。但是,如果您真的這樣認為,那麼您就大錯特錯了。我們知道,Windows是一個以虛拟記憶體為基礎的作業系統。在這種系統環境 下,Windows記憶體管理器經常在記憶體中來回移動對象,依此來滿足各種應用程式的記憶體需要。對象被移動意味着它的位址變化了。如果位址總是如此變化,我 們該到哪裡去找該對象呢?

為了解決這個問題,Windows作業系統為各應用程式騰出一些記憶體儲位址,用來專門登記各應用對象在記憶體中的 位址變化,而這個位址(存儲單元的位置)本身是不變的。Windows記憶體管理器在移動對象在記憶體中的位置後,把對象新的位址告知這個句柄位址來儲存。這 樣我們隻需記住這個句柄位址就可以間接地知道對象具體在記憶體中的哪個位置。這個位址是在對象裝載(Load)時由系統配置設定給的,當系統解除安裝時 (Unload)又釋放給系統。

句柄位址(穩定)→記載着對象在記憶體中的位址────→對象在記憶體中的位址(不穩定)→實際對象

本質:WINDOWS程式中并不是用實體位址來辨別一個記憶體塊,檔案,任務或動态裝入子產品的,相反的,WINDOWS API給這些項目配置設定确定的句柄,并将句柄傳回給應用程式,然後通過句柄來進行操作。

但 是必須注意的是程式每次從新啟動,系統不能保證配置設定給這個程式的句柄還是原來的那個句柄,而且絕大多數情況的确不一樣的。假如我們把進入電影院看電影看成 是一個應用程式的啟動運作,那麼系統給應用程式配置設定的句柄總是不一樣,這和每次電影院售給我們的門票總是不同的一個座位是一樣的道理。

 http://blog.csdn.net/upwaker/archive/2004/07/04/33827.aspx

先來看些權威的片斷:

...

typedef unsigned int HANDLE;

#define DECLARE_HANDLE(name) typedef UINT name

DECLARE_HANDLE(HMODULE);

DECLARE_HANDLE(HINSTANCE);

DECLARE_HANDLE(HLOCAL);

DECLARE_HANDLE(HGLOBAL);

DECLARE_HANDLE(HDC);

DECLARE_HANDLE(HRGN);

DECLARE_HANDLE(HWND);

DECLARE_HANDLE(HMENU);

DECLARE_HANDLE(HACCEL);

DECLARE_HANDLE(HTASK);

...

#define DECLARE_HANDLE(x) typedef WORD x

...

//+-------------------------------------------------------------------------

// DECLARE_HANDLE Macro

//--------------------------------------------------------------------------

#ifndef DECLARE_HANDLE

#define DECLARE_HANDLE(name) /

struct name##__ { DWORD unused; }; /

typedef struct name##__ _far* name

#endif

...

知道本質了吧~~~~

WINDOWS程式中并不是用實體位址來辨別一個記憶體塊,檔案,任務或動态裝入子產品的,相反的,WINDOWS API給這些項目配置設定确定的句柄,并将句柄傳回給應用程式,然後通過句柄來進行操作。

在< <WINDOWS程式設計短平快>>(南京大學出版社)一書中是這麼說的:句柄是WONDOWS用來辨別被應用程式所建立或使用的對象的唯 一整數,WINDOWS使用各種各樣的句柄辨別諸如應用程式執行個體,視窗,控制,位圖,GDI對象等等。WINDOWS句柄有點象C語言中的檔案句柄。

從 上面的2個定義中的我們可以看到,句柄是一個辨別符,是拿來辨別對象或者項目的,它就象我們的姓名一樣,每個人都會有一個,不同的人的姓名不一樣,但是, 也可能有一個名字和你一樣的人。從資料類型上來看它隻是一個16位的無符号整數。應用程式幾乎總是通過調用一個WINDOWS函數來獲得一個句柄,之後其 他的WINDOWS函數就可以使用該句柄,以引用相應的對象。在WINDOWS程式設計中會用到大量的句柄,比如:HINSTANCE(執行個體句柄), HBITMAP(位圖句柄),HDC(裝置描述表句柄),HICON(圖示句柄)等等,這當中還有一個通用的句柄,就是HANDLE,比如下面的語句:

HINSTANCE hInstance;

可以改成:

HANDLE hInstance;

上面的2句語句都是對的。

一 個WINDOWS應用程式可以用不同的方法獲得一個特定項的句柄。許多API函數,諸如CreateWindow,GlobalAlloc, OpenFile的傳回值都是一個句柄值。另外,WINDOWS也能通過應用程式的引出函數将一個句柄作為參數傳送給應用程式,應用程式一旦獲得了一個确 定項的句柄,便可在WINDOWS環境下的任何地方對這個句柄進行操作。其實句柄的大量使用已經影響到了每一個WINDOWS的程式設計。

句 柄隻有當唯一的确定了一個項目的時候,它才開始有意義。句柄對應着項目表中的一項,而隻有WINDOWS本身才能直接存取這個表,應用程式隻能通過API 函數來處理不同的句柄,舉個例子來說吧!比如:我們可以為我們的應用程式申請一塊記憶體塊,通過調用API函數GlobalAlloc,來傳回一個句柄值:

hMem=GlobalAlloc(......);

其實作在hMem的值隻是一個索引值,不是實體位址,應用程式還 不能直接存取這塊記憶體。這兒還有一個話外題,就是,一般情況下我們在程式設計的時候,給應用程式配置設定的記憶體都是可以移動的或者是可以丢棄的,這樣能使有限的内 存資源充分利用,是以,在某一個時候我們配置設定的那塊記憶體的位址是不确定的,因為他是可以移動的,是以得先鎖定那塊記憶體塊,這兒應用程式需要調用API函數 GlobalLock函數來鎖定句柄。如下:

lpMem=GlobalLock(hMem);

這樣應用程式才能存取這塊記憶體。

http://bbs.xiakexing.com/cgi-bin/topic.cgi?forum=36&topic=16&show=0

1.句柄是什麼?

   在windows中,句柄是和對象一一對應的32位無符号整數值。對象可以映射到唯

一的句柄,句柄也可以映射到唯一的對象。

2.為什麼我們需要句柄?

   更準确地說,是windows需要句柄。windows需要向程式員提供必要地程式設計接口

,在這些接口中,允許程式員通路、建立和銷毀對象。但是,出于封裝地考慮,wi

ndows并不想向程式員傳回指針。指針包含了太多的資訊。首先指針給出了對象存儲

的确切位置;其次,要操作一個指針,程式員必須知道指針所指對象的内部結構特

征,也即,windows必須向程式員暴露相應的資料結構,而這些資料結構也許是操作

系統想向程式員隐藏的。

   如果說COM技術向使用者隐藏了資料,隻暴露了接口并隻允許按接口定義的方法操

作資料的話,句柄這種方式則允許你按自己的方式直接操作資料,但windows又不向

你直接暴露資料。直接操作資料是程式員需要的,不暴露資料是windows所需要的,

句柄封裝方式實作了各取所需。

3.句柄如何與對象映射?

   封裝背後,必須有一個地方可以實作解碼,以實作句柄和對象的互相轉換。在

windows中,存在兩種映射方式:

   a. 全等映射。也即,句柄本身就是一個指針。映射在這裡隻是類型轉換而已。

這種情況有,程序執行個體句柄或子產品句柄,以及資源句柄等等。

   b. 基于表格的映射。這是對象指針與句柄之間最普通的映射機制。作業系統創

建表格,并儲存所有要考慮的對象。需要建立新對象時,要先在表格中找到空入口

,然後把表示對象的資料添入其中。當對象被删除時,它的資料成員和其在表中的

入口被釋放。

4.句柄的定義和實作

   我們以GDI對象為例進行讨論。建立了GDI對象,就會得到該對象的句柄。句柄

的對象可能是HBRUSH、HPEN、HFONT或HDC中的一種,這依賴于你建立 的GDI對象類

型。但是最普通的GDI對象類型是HGDIOBJ。HGDIOBJ被定義成空指針。

   HPEN的實際編譯類型定義随編譯時間宏STRICT的不同而不同。如果STRCIT已經

被定義了,HPEN是這樣的:

   struct HPEN__ {int unused};

   typedef struct HPEN__* HPEN;

   如果STRICT沒有定義,HPEN是這樣定義的:

   typedef void *HANDLE;

   typedef HANDLE HPEN;

   上面這段代碼是一個注重細節的程式員最接近句柄的地方,是以我們重點分析

一下。這裡有一點點技巧。如果定義了STRICT宏,HPEN是指向有單個未使用字段的

結構的指針,否則HPEN是空指針。C/C++編譯器允許把任何類型的指針作為空指什傳

遞,反之則不可以。兩個不同類型的非空指針是互不相容的。在STRICT版本中,編

譯對GDI對象句柄的不正确混用将給出警告,對于非GDI句柄,如HWND、HMENU的不正

确混用也會給出警告,進而使程式在編譯器得到更STRICT的檢查。

   接下來的分析可能不那麼令你感興趣,但它更深刻地揭示了句柄。對GDI句柄來

說,盡管windows頭檔案把它定義成指針,但如果你仔細檢查這些句柄的值,它根本

就不像指針,這也是為什麼我說它隻是一個32位無符整數值的原因。對句柄就是指

針的情況,這句話也仍然适用。讓我們随意地生成一些句柄,比如你用GetStockOb

ject()以得到一些句柄,你會發現,它們的值總在區間0x01900011到0xba040389。

前者指向使用者區中的未配置設定的無效區域,後者指向核心位址空間。另外你可能發現

,兩個句柄之間的值可能隻差數值1,這也說明GDI句柄不是指針。

   和多數人想象的不一樣,句柄也不是一個單純的索引值。對GDI對象句柄來說,

GDI句柄由8位 、1位堆對象标記(表明對象是否建立在堆中)、7位對象類型資訊和

高4位為0的16位索引組成,如圖:

3 3 2 2 2 2 2 2  2  2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0

1 0 9 8 7 6 5 4  3  2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

|  8 位引用計數 |堆 |  對象類型7  |            16位索引           |

                标

                記

在這裡你可以看到,對GDI來說,它隻使用了16位作為索引。這意味着一個程序最多隻

可以建立小于64K個句柄,實際上受其他一些限制,整個windwos系統中大概可以容納約

16384(0x4000)個GDI對象。

【主要内容取自windows圖形程式設計,袁峰著。稍作整理,應該不影響正确性。】

繼續閱讀