顯式鏈接到一個輸出符號

一旦DLL模塊被顯式加載,線程就必須獲取它要引用的符號的地址,方法是調用下面的函數:

FARPROC GetProcAddress(

    HINSTANCE hinstDll,

    PCSTR pszSymbolName);

參數hinstDll是調用LoadLibrary(Ex)或GetModuleHandle函數而返回的,它用於設定包含符號的DLL的句柄。參數pszSymbolName可以採用兩種形式。第一種形式是以0結尾的字符串的地址,它包含了你想要其地址的符號的名字:

FARPROC pfn = GetProcAddress(hinstDll, "SomeFuncInDll");

注意,參數pszSymbolName的原型是PCSTR,而不是PCTSTR。這意味着GetProcAddress函數只接受ANSI字符串,決不能將Unicode字符串傳遞給該函數,因爲編譯器/鏈接程序總是將符號名作爲ANSI字符串存儲在DLL的輸出節中。

參數pszSymbolName的第二種形式用於指明你想要其地址的符號的序號:

FARPROC pfn = GetProcAddress(hinstDll, MAKEINTRESOURCE(2));

這種用法假設你知道你需要的符號名被DLL創建程序賦予了序號值2。同樣,我要再次強調,Microsoft非常反對使用序號,因此你不會經常看到GetProcAddress的這個用法。

這兩種方法都能夠提供包含在DLL中的必要符號的地址。如果DLL模塊的輸出節中不存在你需要的符號,GetProcAddress就返回NULL,表示運行失敗。

應該知道,調用GetProcAddress的第一種方法比第二種方法要慢,因爲系統必須進行字符串的比較,並且要搜索傳遞的符號名字符串。對於第二種方法來說,如果傳遞的序號尚未被分配給任何輸出的函數,那麼GetProcAddress就會返回一個非NULL值。這個返回值將會使你的應用程序錯誤地認爲你已經擁有一個有效的地址,而實際上你並不擁有這樣的地址。如果試圖調用該地址,肯定會導致線程引發一個訪問違規。我在早期從事Windows編程時,並不完全理解這個行爲特性,因此多次出現這樣的錯誤。所以一定要小心(這個行爲特性是應該避免使用序號而使用符號名的另一個原因)。

原文:http://hi.baidu.com/onlinewan/blog/item/474a2f2db9539637349bf7f4.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章