Inside COM读书笔记------动态链接库
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共享同一进程,因此他们也可以共享同一地址空间,
当客户组件得到一个接口指针时,连接客户和组件的唯一中介是接口的二进制结构。当客户查询组件的够格接口时,他所请求的实际上是具有特定格式的一块内存。当组件返回一个接口指针时,他告诉客户的实际上是此块存储的地址。