已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
IntroductionI have seen quite a lot of code explaining how to use classes exported from a DLL in an application. However, all these describe the usage of the exported classes by linking implicitly to the DLL. Refreshing our DLL concepts, there are two ways for an application to use a function written in a DLL. The first way is to have your applications source code simply reference symbols contained in the DLL. This causes the loader to implicitly load (and link) the required DLL when the application is invoked. This is known as implicit linking.The second way is for the application to explicitly load the required DLL (using a LoadLibrary() call) and explicitly link to the desired exported symbol while the application is running. In other words, if the application decides that it wants to call a function in a DLL, it can explicitly load the DLL into the process address space, get the virtual memory address of the function contained within the DLL, and then call the function using this memory address. The beauty of this technique is that everything is done while the application is running and the application can unload the DLL from its process address space when it has finished its work with the DLL. As you might have guessed, this technique is known as explicit linking.BackgroundSo far, I spoke of using functions, but hey, what about using classes exported from a DLL? Well, in the case of implicitly linked DLLs, there is no difference at all. But what about loading DLLs explicitly and using the exported classes? Well, under normal circumstances, it cannot be done, but I wrote this article not to explain to you why it cannot be done, but to give you an idea as to how you can do it. Thats right! Using exported classes by loading a DLL using a LoadLibrary() call.But before proceeding further, I warn you that the method given below is sort of a hack, and if for any reason you plan to use it in your project, please take the prior approval of your boss . (if by any chance you do manage to get his/her approval on this technique!). However, this column is basically for your understanding and also for extreme cases when you just cant do without this hack.Using the codeIf you look at the sample code, you can see that I have created a Calculator DLL called Calc.DLL and I am using the calculating powers present in the DLL in my console application called UserOfCalc (I couldnt think of a better name!).Collapse/ Calc.DLL contains an exported class/ called CCalc that contains 3 methods called Add,Sub and GetLastFunc (). It is as follows:/ CALC.H - declares the CCalc class/ that is exported from the DLL/ and is imported in the EXE#include #ifdef CALC_EXPORTS#define CALC_API _declspec (dllexport)#else#define CALC_API _declspec (dllimport)#endif#define SOME_INSTN_BUF 260class CALC_API CCalcprivate:TCHAR m_szLastUsedFuncSOME_INSTN_BUF;public: CCalc (); int Add (int i, int j); int Sub (int i, int j); TCHAR* GetLastUsedFunc ();The implementation of this DLL is as shown in the file Calc.cpp:Collapse#include Calc.h#include BOOL APIENTRY DllMain (HANDLE, DWORD, LPVOID) return TRUE;/ Ctor, initializes the m_szLastFuncCalled arrayCCalc:CCalc () memset (m_szLastUsedFunc, 0, sizeof (m_szLastUsedFunc); strcpy (m_szLastUsedFunc, No function used yet);int CCalc:Add (int i, int j) strcpy (m_szLastUsedFunc, Add used); return (i + j);int CCalc:Sub (int i, int j) strcpy (m_szLastUsedFunc, Sub used); return (i - j);Now, how do we use the functions present in this Calc class by explicitly loading the DLL? The steps are as follows:1. The first step is to load the Calc.DLL library in your application using LoadLibrary. CollapseHMODULE hMod = LoadLibrary (Calc.dll);if (NULL = hMod) printf (LoadLibrary failedn); return 1;2. Since you have the header file of Calc.DLL, the next step is to allocate a block of memory that matches the class layout, and call your constructor code. CollapseCCalc *pCCalc = (CCalc *) malloc (sizeof (CCalc);if (NULL = pCCalc) printf (memory allocation failedn); return 1;But why in the C+ world are we using malloc instead of new! Because the new operator calls CCalcs constructor for which we dont have any access. Remember, we have to load the DLL dynamically and hence there is no definition of CCalcs constructor available to us at build time.Hence we just obtain an uninitialized block of memory whose size equals the CCalc class size.3. If you look up the exported functions in Dumpbin.exe (thats located under your Microsoft Visual StudioVC98Bin directory), and type dumpbin /exports, you will see a list of functions exported by the DLL. (By the way, I have used a DEF file to unmangle the mangled function names.) It is as shown in the figure. The list contains the virtual memory address of the functions Add, Sub, GetLastUsedFunc and the constructor.Since we obtained the block of memory, we have to call the constructor to initialize the block of memory. So, we get the relative virtual address of the constructor in the DLL.CollapsePCTOR pCtor = (PCTOR) GetProcAddress (hMod, CCalc);if (NULL = pCtor) printf (GetProcAddress failedn); return 1;PCTOR is a function pointer and is present at the top of UserOfCalc.cpp. It is defined as follows:Collapsetypedef void (WINAPI * PCTOR) ();4. Since we have the address of the constructor, we have to explicitly call it to initialize the block of memory obtained by malloc. Yes, but how do we associate an object for the constructor? If you remember, when any member function is called, including the constructor, the address of the object gets quietly passed to the called function and this address is stored in the stack. On an Intel based machine, this address of the object is pushed onto the stack via the ECX register. So, if you create a class and call its member function, the ECX register contains the this pointer. This screen shot should make things clearer.If you observe the disassembly window, just after the execution of the line: CollapseLEA ECX, EBP-4you will see that the contents of ECX and &bmw are the same. On a machine having a different processor architecture, it could be another register instead of ECX. We just have to figure that out.5. Coming back to our Calc.dll, since we already have the address of a block of memory (that will in the future be an object), we move this address into the ECX register by using the Visual C+ inline assembler syntax: Collapse_asm MOV ECX, pCCalc 6. Since we have already obtained the address of the constructor, we just say: CollapsepCtor ();7. When your function pointer pCtor() returns from the DLL, it would have initialized the object of the class contained in the DLL. Voila! 8. To call any other member function of the Calc class, once again move pCalc to ECX and obtain the proc address of the exported function and simply
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 濱州學(xué)院《曲式》2023-2024學(xué)年第一學(xué)期期末試卷
- 濱州學(xué)院《材料與工藝》2023-2024學(xué)年第一學(xué)期期末試卷
- 畢節(jié)職業(yè)技術(shù)學(xué)院《商務(wù)英語閱讀3》2023-2024學(xué)年第一學(xué)期期末試卷
- 畢節(jié)醫(yī)學(xué)高等??茖W(xué)校《應(yīng)用物理化學(xué)實驗》2023-2024學(xué)年第一學(xué)期期末試卷
- 北京中醫(yī)藥大學(xué)東方學(xué)院《中國古代建筑與風(fēng)水地理》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025年度茶葉包裝設(shè)計與生產(chǎn)定制合同3篇
- 三方代理合同定稿
- 2025版預(yù)拌砂漿研發(fā)與技術(shù)轉(zhuǎn)讓合同3篇
- 委托養(yǎng)羊合同
- 2025版虛擬現(xiàn)實技術(shù)應(yīng)用與開發(fā)技術(shù)服務(wù)合同3篇
- 河道汛期施工防洪防汛應(yīng)急預(yù)案
- 漢語教程我聽過鋼琴協(xié)奏曲黃河課件
- 二氧化碳充裝流程
- 12m跨鋼棧橋設(shè)計計算
- 電路板類英語詞匯
- DES算法Matlab代碼
- 沙特的礦產(chǎn)資源開發(fā)概況及其商機
- 高一生物必修一期末試題(附答案)
- 安全事故應(yīng)急響應(yīng)程序流程圖(共1頁)
- 三年級_上冊牛津英語期末試卷
- 損傷容限設(shè)計基本概念原理和方法PPT課件
評論
0/150
提交評論