全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1658
推到 Plurk!
推到 Facebook!

DLL載入

尚未結案
LLP
一般會員


發表:3
回覆:8
積分:2
註冊:2004-12-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-04-12 16:42:13 IP:61.66.xxx.xxx 未訂閱
各位先進們好,我是BCB新手,所以有幾件事想請教先進們.... 為了使主程式能夠不變的情況下,利用DLL(Explicitly link)載入主程式中, 但是當DLL內的function name改變時則必須於對應的主程式中修改才可正常使用,所以想於兩者中間再加上一個middle ware(DLL),用意在於能變更DLL的function name與主程式的function name相同(類似轉譯的功能),不知各位先進是否有方法可以提供小妹參考.... 謝謝各位先進!!!!!
shinlo
一般會員


發表:7
回覆:15
積分:9
註冊:2002-04-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-04-12 17:04:28 IP:202.145.xxx.xxx 未訂閱
請問一下....您的意思是... 在不更動主程式之下....同樣載入您的DLL檔... 但是有可能發生DLL檔裡的Function Name跟您的主程式呼叫的名稱不一樣... 您是想做一個中介檔來轉換不一樣的部分(在不修改主程式跟DLL檔的情況下) 您是要問這個嗎?
LLP
一般會員


發表:3
回覆:8
積分:2
註冊:2004-12-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-04-12 17:36:21 IP:220.228.xxx.xxx 未訂閱
Shinlo大大, 我的問題正如您所述,請問大大是否有好的方法? 謝謝!!!
shinlo
一般會員


發表:7
回覆:15
積分:9
註冊:2002-04-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-04-12 19:16:05 IP:202.145.xxx.xxx 未訂閱
你可以試著做一個新的DLL檔....由這個新的DLL檔來幫你呼叫外部的DLL檔... 然後原來的主程式呼叫這個新的DLL檔就行了..... 您可以在您新創的DLL檔裡做個功能就是....自動判別您特定的目錄裡所存放的 DLL是屬於哪一個....例如您有A,B,C三個DLL檔,您就將這三種DLL檔裡的Function Name用switch case的方式, 做Mapping的動作,所以當你主程式開啟時,載入您新創的DLL檔,也同時啟動判別 哪一種DLL檔,然後由這個新的DLL檔自動幫你做Mapping的動作..... 不知道這樣的描述是否是您想要的....^^"
jcjroc
高階會員


發表:21
回覆:279
積分:115
註冊:2002-09-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-04-13 08:02:19 IP:211.75.xxx.xxx 未訂閱
引言: 各位先進們好,我是BCB新手,所以有幾件事想請教先進們.... 為了使主程式能夠不變的情況下,利用DLL(Explicitly link)載入主程式中, 但是當DLL內的function name改變時則必須於對應的主程式中修改才可正常使用,所以想於兩者中間再加上一個middle ware(DLL),用意在於能變更DLL的function name與主程式的function name相同(類似轉譯的功能),不知各位先進是否有方法可以提供小妹參考.... 謝謝各位先進!!!!!
ㄏㄏㄏ,看起來你比較像是要自己寫一個GetProcAddress 如何?你的問題應該這樣就解決掉了
LLP
一般會員


發表:3
回覆:8
積分:2
註冊:2004-12-06

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-13 08:45:42 IP:192.72.xxx.xxx 未訂閱
引言: 你可以試著做一個新的DLL檔....由這個新的DLL檔來幫你呼叫外部的DLL檔... 然後原來的主程式呼叫這個新的DLL檔就行了..... 您可以在您新創的DLL檔裡做個功能就是....自動判別您特定的目錄裡所存放的 DLL是屬於哪一個....例如您有A,B,C三個DLL檔,您就將這三種DLL檔裡的Function Name用switch case的方式, 做Mapping的動作,所以當你主程式開啟時,載入您新創的DLL檔,也同時啟動判別 哪一種DLL檔,然後由這個新的DLL檔自動幫你做Mapping的動作..... 不知道這樣的描述是否是您想要的....^^"
Shinlo 大大您好, 您的方法正式我想做的方式,我試試看用switch case的方法,請問大大是否有相關的範例或資料可供參考?? Thanks!! Dear jcjroc大大, 您所說的使用GetProcAddress的方式,是mapping到DLL內的function,若是套入Shinlo大大的方法內是否可行?小妹我是新手,若是有錯誤之處敬請見諒.Thanks!
shinlo
一般會員


發表:7
回覆:15
積分:9
註冊:2002-04-14

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-04-13 13:45:21 IP:202.145.xxx.xxx 未訂閱
for LLP 小姐..... 您可以使用jcjorc兄所提供的方法來做..... 至於怎麼用...您可以用關鍵字GetProcAddress來搜索本站..... 您應該可以看到很多相關的文章....相信GetProcAddress這個API怎麼用 您應該會了解...... 至於我使用switch case的想法....您可以先將您可能使用到的DLL檔 分別給他們一個代號....然後用搜索檔案的方式...看看找到的是哪一個DLL檔 那就進入哪一個相對的case裡去執行GetProcAddress這個API...... 依照不同的DLL去做相對的Function Mapping...... 也就是外部的DLL被您自創的DLL呼叫並做判別與Mapping.... 然後再由您的主程式去呼叫您的自創DLL檔即可.... 至於sample....抱歉...我最近比較忙...沒有時間寫... 不過您可以自己寫數個小型的DLL檔當作外部DLL..... 再用我的想法與jcjroc兄所提供的方法來製作自創的DLL來實驗.... 我想這樣您可以更有印象....^^ 如果您實驗成功之後,如果可以的話...也希望您可以分享您成功的心得與程式碼....^^
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-04-13 15:12:16 IP:219.84.xxx.xxx 未訂閱
LLP你好: 如果只有function name改變,而return type, parameters, calling convention是一樣的話,可以不需要重新編譯就能直接叫用。如果改變的只是parameters的話,也可以用一個class包裝parameter。之後如果要變parameters的話,只要製作subclass即可,主程式也不用重新編譯。 至於return type和calling convention的改變,就只能借助另一個函式來轉接了。
LLP
一般會員


發表:3
回覆:8
積分:2
註冊:2004-12-06

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-04-13 15:28:26 IP:210.80.xxx.xxx 未訂閱
引言: LLP你好: 如果只有function name改變,而return type, parameters, calling convention是一樣的話,可以不需要重新編譯就能直接叫用。如果改變的只是parameters的話,也可以用一個class包裝parameter。之後如果要變parameters的話,只要製作subclass即可,主程式也不用重新編譯。 至於return type和calling convention的改變,就只能借助另一個函式來轉接了。
Pwipwi大大您好, 關於您說的function name改變可以不需重新編譯就能直接叫用,是不是指主程式需要做改變(calling DLL with function name),但是我的問題是...在不變動主程式的狀況下能夠叫用不同於主程式(function name)的外部DLL function,小妹才疏學淺,請pwipwi大大不吝賜教.....
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-04-13 15:55:52 IP:219.84.xxx.xxx 未訂閱
LLP你太客氣了,我上面的文章中有些地方沒有回的很清楚.. 在Dll中做一個函式,名字和主程式呼叫的function名字相同,參數和回傳值也要一樣。之後再在呼叫轉到你要的函式上即可。 另外一個方法是修改PE內容,有不少工具可以做到,把名子改一下就沒問題了,連轉接函式也不用寫。
LLP
一般會員


發表:3
回覆:8
積分:2
註冊:2004-12-06

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-04-13 16:05:26 IP:220.228.xxx.xxx 未訂閱
pwipwi大大您好, 可否請您再描述的詳細一點點...,因為我不是很懂您的意思... 若可以請提供範例或資料給小妹參考一下....Thanks a lot!!!
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-04-13 20:09:49 IP:219.84.xxx.xxx 未訂閱
有一本侯捷翻譯的絕版書windows95 system programming secrets,裡面有Dll如何從PE取得函式進入點的資料。這本書可以從他網站上下載,是研究windows架構不可少的一本書。 建議你可以參考有關Export Function的部份,和你的問題有很大的關係。之後有了概念就可以用現在的工具或自已去實作程式。
jcjroc
高階會員


發表:21
回覆:279
積分:115
註冊:2002-09-18

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-04-14 08:33:12 IP:211.75.xxx.xxx 未訂閱
其實我講的已經很明確了,GetProcAddres顧名思義,他返回的是一個4Byte的Function進入點,呼叫端再將此值轉換成一個函式原型爾後呼叫他.
typedef BOOL (WINAPI* API_Win32NLSEnableIME)(HWND hWnd,BOOL Enable);    API_Win32NLSEnableIME API_Win32NLSEnableIMEPtr=NULL;
HMODULE HModule=::GetModuleHandle("USER32.DLL");
if(NULL==HModule)
            HModule=::LoadLibrary("USER32.DLL");
if(HModule)
           API_Win32NLSEnableIMEPtr=(API_Win32NLSEnableIME)::GetProcAddress(HModule,"Win32NLSEnableIME");
if(NULL!=API_Win32NLSEnableIMEPtr)
         return API_Win32NLSEnableIMEPtr(hWnd,Enable);    
當GetProcAddress將Function Pointer取回而未轉型前,對C或其他中高階語言來說是無法直接呼叫使用的,但低階語言(如ASM)是可以使用的. 當你對此Function Pointer轉型後,Compiler會根據你對此Function Pointer的定義,檢查你呼叫他時是否合乎定義,當然往後還很的事,但一切都是參照你的定義來作. 如果對這方面有興趣,可以去找一些較進階的書來研究,在此不再贅述. 所以我叫你自己做一個GetProcAddress道理就在這裡,你只負責將找到的4Byte的Function Pointer回傳就好,至於其他如參數,說句話,你管不著. 至於怎找?唉!黑貓白貓,會抓老鼠的就是好貓. 你提的這問題不關BCB新手,在我看來是基礎觀念問題.
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-04-14 10:43:27 IP:219.84.xxx.xxx 未訂閱
重寫GetProcAddress很明顯是個下下之策。 LLP網友已經提到"不更動主程式"。GetProcAddress不正是主程式要叫用的嗎? 在提這是"基礎觀念"之前,請先了解發問者的問題。 另外,我寫過解讀PE內容的函式,Export Table裡面結構也有一定的複雜度。如果jcjroc如果可以提供GetProcAddress的程式碼的話,再提這個建議會比較好一些。
jcjroc
高階會員


發表:21
回覆:279
積分:115
註冊:2002-09-18

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-04-14 12:18:55 IP:211.75.xxx.xxx 未訂閱
引言: 重寫GetProcAddress很明顯是個下下之策。 LLP網友已經提到"不更動主程式"。GetProcAddress不正是主程式要叫用的嗎? 在提這是"基礎觀念"之前,請先了解發問者的問題。 另外,我寫過解讀PE內容的函式,Export Table裡面結構也有一定的複雜度。如果jcjroc如果可以提供GetProcAddress的程式碼的話,再提這個建議會比較好一些。
那改名叫做MyGetProcAddress好了 我如果沒看錯的話,他要的是一個中繼轉介的東西. 所以這個MyGetProcAddress接受的參數當然是設計者自己定義,而不是使用者. 重要的是返回的Function Pointer 至於怎找到對應的Function Pointer,就各自去發揮了 問題在於這個方式是否符合需求而已. 寫這個MyGetProcAddress我想沒啥困難性吧?
shinlo
一般會員


發表:7
回覆:15
積分:9
註冊:2002-04-14

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-04-14 13:23:15 IP:202.145.xxx.xxx 未訂閱
我是想說.....提供一個比較直覺的想法給LLP小姐作為參考....    所以我覺得可以先不要就程式效率而言,而去使用一些比較艱深的API.... (不好意思...多有得罪請多包涵)    如果LLP小姐對於基本的DLL建構有一定的概念的話,那您可以把DLL當作    一般寫程式的CPP來做....    您可以自創一個DLL檔(把它當作CPP)....然後用他來呼叫妳可能要使用的    外部DLL(假設有很多種)....    那你可以在程式裡面創建一些Function....而這些Function是相對應於外部的DLL (也就是DLL裡面你所要用的Function需要什麼引數,會回傳什麼型態的值)    然後用switch case選擇你所要用的DLL檔..... (當然您可以寫個搜索檔案的Function)    例如您的外部DLL檔有A,B,C三種....您對這三種各自定義為1,2,3    所以如果你找到B.DLL,那您就會進入到2的case...以此類推....    例如您想要使用某個Function.....只是差在不同的DLL檔有不同的Function Name    那您在自創的DLL檔裡創建一個你主程式裡要呼叫的Function Name    然後在這個Function裡再去呼叫外部DLL的Function Name    ex:     
int __fastcall TTest::GetValue(int x, int y)
{        switch(dllcase)
    {
        case 1:
        A_GetValue(x,y);
        break;
        case 2:
        B_GetValue(x,y);
        break;
        case 3:
        C_GetValue(x,y);
        break;
    }    }
(GetValue是您主程式裡所要呼叫的Function Name....A_GetValue是A.DLL裡的Function...以此類推) 上式只是一個概念....看你有幾個Function要呼叫...就做幾個類似的Function 不過切記....你的主程式是呼叫自創的DLL...而自創的DLL要呼叫的則是外部的DLL 而且你在自創的DLL裡,要注意自創的Function是否跟你要呼叫的外部DLL 所用的引數跟回傳是否一致...... 我的方法比較沒效率....也比較笨....但是應該是蠻直覺的.... 提供給各位參考看看....(主要是針對LLP,因為她說她是新手....^^")
系統時間:2024-05-14 16:48:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!