天天看點

handle句柄 matlab_句柄(Handle)

在程式設計中經常會碰到句柄這個術語,百度百科上的定義是:“句柄是一個是用來辨別對象或者項目的辨別符,可以用來描述窗體、檔案等“。為了更好地了解句柄,下面研究一個具體的句柄來體會其用處。下面針對MATLAB中常出現的function handle學習。在MATLAB官方文檔中對其定義和描述如下:A function handle is a MATLAB® data type that stores an association to a function. Indirectly calling a function enables you to invoke the function regardless of where you call it from. Typical uses of function handles include:

1. Pass a function to another function (often called function functions). For example, passing a function to integration and optimization functions, such as integral and fzero.

2. Specify callback functions. For example, a callback that responds to a UI event or interacts with data acquisition hardware.

3. Construct handles to functions defined inline instead of stored in a program file (anonymous functions).

4. Call local functions from outside the main function.

To create a handle for a function, precede the function name with an @ sign. For example, if you have a function called myfunction, create a handle named f as follows:

f = @myfunction;

簡單來說,函數句柄是一種資料類型,它提供了一個接口讓你可以在任意位置間接調用與之關聯的函數。可是為什麼要用句柄呢,函數指針不是也可以嗎?

為什麼不用函數指針或者首位址?Windows系統中有許多核心對象(這裡的對象不完全等價于"面向對象程式設計"一詞中的"對象",雖然實質上還真差不多),比如打開的檔案,建立的線程,程式的視窗,等等。這些重要的對象肯定不是4個位元組或者8個位元組足以完全描述的,他們擁有大量的屬性。為了儲存這樣一個"對象"的狀态,往往需要上百甚至上千位元組的記憶體空間,那麼怎麼在程式間或程式内部的子過程(函數)之間傳遞這些資料呢?拖着這成百上千的位元組拷貝來拷貝去嗎?顯然會浪費效率。那麼怎麼辦?當然傳遞這些對象的首位址是一個辦法,但這至少有兩個缺點:

1. 暴露了核心對象本身,使得程式(而不是作業系統核心)也可以任意地修改對象地内部狀态(首位址都知道了,還有什麼不能改的?),這顯然是作業系統核心所不允許的;

2. 作業系統有定期整理記憶體的責任,如果一些記憶體整理過一次後,對象被搬走了怎麼辦?

是以,Windows作業系統就采用進一步的間接:在程序的位址空間中設一張表,表裡頭專門儲存一些編号和由這個編号對應一個位址,而由那個位址去引用實際的對象,這個編号跟那個位址在數值上沒有任何規律性的聯系,純粹是個映射而已。 在Windows系統中,這個編号就叫做"句柄"。

也就是說,如果不在乎浪費空間的話,在某些情況下可以不使用句柄,直接對檔案進行操作。

從廣義上,能夠從一個數值拎起一大堆資料的東西都可以叫做句柄。句柄的英文是"Handle",本義就是"柄",隻是在計算機科學中,被特别地翻譯成"句柄",其實還是個"柄"。從一個小東西拎起一大堆東西,這難道不像是個"柄"嗎?

然後,指針其實也是一種"句柄",隻是由于指針同時擁有更特殊的含義——實實在在地對應記憶體裡地一個位址——是以,通常不把指針說成是"句柄"。但指針也有着能從一個32位的值引用到一大堆資料的作用,這不是句柄又是什麼?

handle與程序ID、HINSTANCE的差別1、先來談談Handle

Handle本身是一個32位的無符号整數,它用來代表一個核心對象。它并不指向實際的核心對象,使用者模式下的程式永遠不可能獲得一個核心對象的實際位址(一般情況下)。那麼Handle的意義何在?它實際上是作為一個索引在一個表中查找對應的核心對象的實際位址。那麼這個表在哪裡呢?每個程序都有這樣的一個表,叫句柄表。該表的第一項就是程序自己的句柄,這也是為什麼你調用GetCurrentProcess()總是傳回0x7FFFFFFF原因。

簡單地說,Handle就是一種用來"間接"代表一個核心對象的整數值。你可以在程式中使用handle來代表你想要操作的核心對象。這裡的核心對象包括:事件(Event)、線程、程序、Mutex等等。我們最常見的就是檔案句柄(file handle)。

另外要注意的是,Handle僅在其所屬的程序中才有意義。将一個程序擁有的handle傳給另一個程序沒有任何意義,如果非要這麼做,則需要使用DuplicateHandle(),在多個程序間傳遞Handle是另外一個話題了,與這裡要讨論的無關。

2、程序ID

首先,程序ID是一個32位無符号整數,每個程序都有這樣的一個ID,并且該ID在系統範圍内是唯一的。系統使用該ID來唯一确定一個程序。

深入些說,系統可能使用程序ID來計算代表該程序的核心對象的基位址(及EPROCESS結構的基位址),具體的計算公式你可以去問微軟的OS開發人員。

3、HINSTANCE

HINSTANCE也是一個32無符号整數,它表示程式加載到記憶體中的基位址。