精華區beta C_and_CPP 關於我們 聯絡資訊
之前有發文問過 目前觀念是使用dll有兩種方法 implicit link 和 explicit link explicit link似乎就是用loadlibrary / GetProcAddress方式 搭配.h implicit link似乎就是 dll要搭配lib給 也要搭配.h 我和一個朋友詢問 他不是很清楚原理 但是他跟我講他給別人用都只給dll和.h 讓我覺得很難理解 因為他.h裡面有class 用explicit link似乎不可行.... 我就去驗證一下 export出來的.h 內容: class TESTDLL_API CTestDLL { public: // TODO: add your methods here. virtual void XD()=0; //不定義給兒子override virtual void ORZ(); //我在cpp定義 }; 另一個.h內容 class Son:CTestDLL { public: void XD(){cout<<"我是derived"<<endl;} } cpp定義 void CTestDLL::ORZ(){cout<<"我是orz"<<endl;} 順便export一個function 用來產生instance TESTDLL_API void CreateInstance(CTestDLL **ptr) { *ptr = new Son; } 再來是 要使用dll的程式 只加入dll和.h HMODULE hGAL; if (NULL != (hGAL =LoadLibrary(L".\\TestDLL.dll"))) { cout<<"load dll successful"<<endl; typedef void(*FUNPTR)(CTestDLL**); FUNPTR FPTR; FPTR=(FUNPTR)GetProcAddress(hGAL, "CreateInstance"); CTestDLL *ptr; FPTR(&ptr); //以下兩個呼叫 都可以成功印出....... ptr->XD(); ptr->ORZ(); } 以上讓我對為啥要給.lib用implicit link 感到很怪 不知為啥要給lib 然後我就試著把virtual void ORZ(); //我在cpp定義的virtual拿掉 void ORZ(); ptr->ORZ();只要一呼叫就出現link error 對於link error和不link error這原因我沒有觀念... 變成目前結論是你export給別人如果class都是virtual就不用給lib 如果有非virtual就要lib... 如果不用GetProcAddress 來取得CreateInstance 直接呼叫 沒有lib也會link error 可是以上這兩個觀察到的現象 可否給我一個很好理解的觀念.... 我實在不懂為什麼有時要lib有時不用給 感謝!@@ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 219.87.64.222
Bencrie:你的程式碼不是explicit link嗎 @@? 02/09 21:14
QQ29:你好~~我只是為了取得 CreateInstance這函式 02/09 21:15
QQ29:用explicit...其他的我以為要用implicit發現不用 02/09 21:15
QQ29:我的explicit和implicit 只是有沒有用到.lib的差別@@ 02/09 21:16
Bencrie:你用LoadLibrary的時候就是用explicit link了呀 02/09 21:16
QQ29:我把不用lib當成explicit去想 不知道觀念有沒有錯~ 02/09 21:16
QQ29:但是我不加virtual 就無法這樣呼叫了 02/09 21:17
Bencrie:explicit是不用lib檔沒錯,就算DLL檔不存在你的程式還是可 02/09 21:18
Bencrie:以啟動,不會跳出找不到DLL的錯誤視窗。 02/09 21:18
Bencrie:以C的DLL來說,所有要存取的東西都必須GetProc 02/09 21:21
Bencrie:C++的DLL我沒有寫過 orz 不過照理說XD、ORZ也要GetProc 02/09 21:23
Bencrie:還有就是我對GetProcAddress抓得到CreateInstance感到好奇 02/09 21:34
Bencrie:,如果你的CreateInstance沒有extern "C" 修飾的話,他應 02/09 21:34
Bencrie:該會是C++修飾過的函數名稱,用"CreateInstance"還可以回 02/09 21:35
Bencrie:傳正確的address還蠻怪的。 囧a 02/09 21:36
QQ29:有~有把宣告用extern包起來 不過您一開始說的 啟動會錯誤 02/09 22:49
QQ29:是因為用implicit 所以exe必須和dll共存一開始就要load? 02/09 22:50
QQ29:如果動態用 getproc去抓的話應該是 跑到那行才會死吧? 02/09 22:50
Bencrie:http://tinyurl.com/y8ejwzt 這個是Linux用的,class的 02/10 13:23
Bencrie:explicit linking似乎可行,但是要另外做建構子的wrapper 02/10 13:24
> -------------------------------------------------------------------------- < 作者: coldstars (あら~) 看板: C_and_CPP 標題: Re: [問題] dll :implicit link 和 explicit link 時間: Wed Feb 10 02:29:59 2010 ※ 引述《QQ29 (我愛阿蓉)》之銘言: : 變成目前結論是你export給別人如果class都是virtual就不用給lib : 如果有非virtual就要lib... 某方面來說這是對的... 對一般function,和member function來說 要嘛就拿著.lib去一起link,要嘛就GetProcAddress 這兩件事一定要選其中一件來做 必須要告訴linker: 1) 我這邊使用了foo(),而且我也有它的定義 2) 我這邊使用了foo(),而且我知道它在某個dll裡面有,請你去查然後幫我設好 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 這就是.lib告訴linker的事 不然就會報error 但是virtual function不一樣 call virtual function的時候是用某種查表的方式達成的 他大概是這樣做: 1. 把virtual function的address集中到一個表格 2. 在物件construct時,把表格的指標塞進instance裡 3. call virtual function的時候大概這樣: 假設ptr是你物件實體(instance)的指標 table *mytbl = ptr->__vtbl;// 這是隱藏的member,編譯器偷加的 void (*fptr)(CTestDLL * const this) = mytbl[0].addr;// 這個array index編譯器也會負責搞定 fptr(ptr); 所以call virtual function其實不會吃到virtual function本體的定義 當然如果執行時仍然沒有該有的定義,程式就會掛點... 就像把.dll移到其他地方去那樣 回到一開始的問題,現在沒有覺得比較理所當然了? 把一個virtual function變成一般function... 然後沒有提供定義的話,當然不能link call virtual function並不需要定義,所以不管有沒有丟.lib都沒影響 但是construct一個instance時,是需要virtual function定義的 不然那張表格裡要填什麼呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.37.177.28
VictorTom:先推一下, 用力理解中....@_@" 02/10 09:59
TeaEEE:virtual function?似乎與C++容易搞混 直接稱函式指標會不會 02/10 10:06
TeaEEE:清楚點? 02/10 10:07
littleshan:virtual function 本質就是 function pointer 啊... 02/10 10:35
LPH66:二樓 這裡說的就是 C++ 的 virtual function 啊... 02/10 10:44
VictorTom:小弟我和樓上L大有同樣的疑問XD 也推l大的本質:) 02/10 10:51
u941716:了解!感謝! 02/10 11:21
改個錯字 ※ 編輯: coldstars 來自: 114.37.171.147 (02/10 12:08)
QQ29:謝謝我有空趕緊理解 02/10 12:34