1. 組件的創建
在客戶獲取某個組件接口指針之前,必須先將相應的DLL裝載到起進程空間中並創建此組件。
從DLL中輸出函數
先將需要輸出的函數用extern “C”進行標記,如:
extern "C" IUnknown * CreateInstance()
{
IUnknown*pI = (IUnknown*)(void*)new CA;
pI->AddRef();
return pI;
}
在函數的定義前加上extern “C” 可防止C++編譯器在函數名稱上加上類型信息,若不Microsoft加會Visual C++把CreateInstance變成:?Createinstance@@YAPAUUnknown@@XZ,其他編譯器會變成其他某種名稱。
從DLL中輸出函數還需要創建一個DEF函數:
LIBRARY "MyCom Sort"
EXPORTS
;Explicit exports can go here
DllGetClassObjectPRIVATE
DllRegisterServerPRIVATE
DllUnregisterServerPRIVATE
DllCanUnloadNow PRIVATE
上述文件在EXPORTS段中列出待從DLL中輸出地函數的名稱。對每一個名稱可以加上一個序號。LIBRARY行上必須加上DLL的實際名稱。
DLL的裝載
typedefIUnknown* (*CREATEFUNCPTR)() ;
IUnknown* CallCreateInstance(char* name)
{
//Load dynamic link library into process.
HINSTANCEhComponent = ::LoadLibrary(name) ;
if(hComponent == NULL)
{
cout<< "CallCreateInstance:\tError: Cannot load component."<< endl ;
returnNULL ;
}
//Get address for CreateInstance function.
CREATEFUNCPTRCreateInstance
=(CREATEFUNCPTR)::GetProcAddress(hComponent, "CreateInstance") ;
if(CreateInstance == NULL)
{
cout << "CallCreateInstance:\tError:"
<< "Cannot find CreateInstancefunction."
<< endl ;
returnNULL ;
}
returnCreateInstance() ;
}
爲了裝載DLL調用了Win32的LoadLibrary函數,以DLL的名稱爲參數返回一個指向所裝載的DLL的句柄。Win32的GetProcAddress函數可以使用此句柄以及待調用的函數名稱。返回一個函數指針。
動態鏈接庫將駐留在所連接的應用程序的地址空間中,由於DLL和EXE共享同一進程,因此他們也可以共享同一地址空間,
當客戶組件得到一個接口指針時,連接客戶和組件的唯一中介是接口的二進制結構。當客戶查詢組件的夠格接口時,他所請求的實際上是具有特定格式的一塊內存。當組件返回一個接口指針時,他告訴客戶的實際上是此塊存儲的地址。