博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
COM笔记-动态链接
阅读量:4320 次
发布时间:2019-06-06

本文共 2193 字,大约阅读时间需要 7 分钟。

在实现了IUnknown之后,组件和客户之间只是一种非常松散的连接,这使用组件和客户各自可以发生变化而不会对对方造成什么影响。

下面讨论如何将组件放入到动态链接库(dll)中。

关于DLL更多内容可以参考我的其它文章:

http://www.cnblogs.com/fangyukuan/archive/2010/06/20/1761430.html
http://www.cnblogs.com/fangyukuan/archive/2010/06/20/1761464.html
http://www.cnblogs.com/fangyukuan/archive/2010/06/21/1761666.html

组件的创建

在客户可以获取某个组件接口指针之前,它必须先将相应 的DLL装载到其进程空间中并创建此组件。这里创建组件的方法是临时性的,后面我还有其它方法(它客户和组件进一步分隔开来)。

之前说到QueryInterface函数的时候给出了CreateInstance可以建立一个组件的实例并给客户返回一个IUnknown接口指针(见:这个函数是DLL中唯一需要显式链接的函数。客户其它所需要的所有函数都可以通过接口指针而访问到。

 

 

DLL中输出CreateInstance函数

extern "C"进行标记要输出的函数

例如:

extern "C"  IUnknown *CreateInstance()

{

IUnknow *pI = (IUnknown *)(void *)new CA;

pI->AddRef();

Return pI;

}

在函数的定义前加上可防止C++ 编译器在函数名称上加上类型信息。例如在不加extern "C"时,Microsoft Visual C++ 将把CreateInstance变成:

CreateInstance@@YAPAUUnknown@@XZ

其它的编译器可能会使用另外某种名称修改方法。

 

还需要建立一个的DEF文件。

LIBRARY Search.dll

EXPORTS

导出函数名

 

DLL的装载

CreateInstance

装载DLL并调用其中所输出的函数

为装载指定的DLLCallCreateInstance调用了Win32LoadLibray函数:

GetProcAddress使用LoadLibray返回的句柄和待调用的函数名称,返回一个指向此函数的指针

FARPROC GetProcAddress(

  HMODULE hModule,

  LPCWSTR lpProcName

);

 

 
typedef IUnknown
*
(
*
CREATEFUNCPTR)();
IUnknown
*
CallCreateInstance(
char
*
name)
{
//
Load dynamic link library into process.
HINSTANCE hComponent
=
::LoadLibraryA(name) ;
if
(hComponent
==
NULL)
{
cout
<<
"
CallCreateInstance:\tError: Cannot load component.
"
<<
endl;
return
NULL;
}
//
Get address for CreateInstance function.
CREATEFUNCPTR CreateInstance
=
(CREATEFUNCPTR)::GetProcAddress(hComponent,
"
CreateInstance
"
);
if
(CreateInstance
==
NULL)
{
cout
<<
"
CallCreateInstance:\tError:
"
<<
"
Cannot find CreateInstance function.
"
<<
endl;
return
NULL;
}
return
CreateInstance();
}

 

 

 

使用DLL的原因

DLL可以共享它们所链和的应用程序的地址空间。

客户和组件是通过接口进行交互的。一个接口实际上是一个指向函数的指针列表(vtbl)。组件为vtbl分配内存并用每个函数的地址来初始化此表格。

为了使用vtbl客户应该能 够访问组件 其vtbl民分配的内存,它还必须能够理解组件放入到vtbl中的各个地址。

 

进程外服务器具有与客户不同的地址空间,但我们将仍然使用Dll来帮助实现进程外服务器同客户之间的交流。如下图显示了DLL如何映射到其客户的地址空间。

2010060923081486.png

 

此外的关键之外在于,当得到组件的一个接口指针时,连接客户和组件的唯一中介是接口的二进制结构。当客户查询组件的某个接口时,它所请求的实际上是具有特定格式的一块内存。当组件返回一个接口指针时,它告诉的实际上是些块内存的地址。

由于接口是在客户和组件都能够访问的内存中,因此这种情况实际上与当然和组件在同一个EXE文件中是相同的。

:http://www.box.net/shared/zhktgzojlj

本文地址: 

 

转载于:https://www.cnblogs.com/fangyukuan/archive/2010/06/09/1755150.html

你可能感兴趣的文章
PHPExcel 使用心得
查看>>
洛谷 P3374 【模板】树状数组 1(单点加,区间和)
查看>>
verilog 代码编写小记
查看>>
PyQT的安装和配置
查看>>
从 docker 到 runC
查看>>
守护进程
查看>>
php数组
查看>>
Linux 防火墙
查看>>
互联网金融P2P主业务场景自动化测试
查看>>
My third day of OpenCV
查看>>
Android的View和ViewGroup分析
查看>>
echarts.js中的图表大小自适应
查看>>
Delphi的FIFO实现
查看>>
牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)
查看>>
(转)AS3 面相对象 高级话题
查看>>
Missile
查看>>
关于kindedit和 Uedit后者兼容前者
查看>>
微软BI 之SSIS 系列 - 利用 SSIS 模板快速开发 SSIS Package
查看>>
eclipse中使用git上传到githup,报401 Authorization Required
查看>>
基于Golang打造一款开源的WAF网关
查看>>