COM技术内幕第五章笔记动态链接

利用动态链接库DLL来实现组件。

DLL只是组件的一种实现方式,组件是DLL中实现的一组接口集。

组件描述的是本质,DLL是形式。

从DLL中输出函数

1、extern “C”

需要输出的函数用extern "C"进行标记,防止C++编译器在函数名称上加上类型信息。

(不同编译器会使用不同的名称修改方法)

// Creation functioni

extern "C"

IUnknown * CreateInstance()

{

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

      pI->AddRef();    // important!!!

      return pI;

}

vc++是,可以用bumpbin.exe来得到某个DLL的符号清单。如

dumpbin -exports cmpnt1.dll

2、建立DEF函数

除了在函数前加上extern “C”标记,为了从DLL中输出函数,还需要告诉链接程序需要输出什么函数。

为此需要建立一个DEF函数。

vs2005 ActiveX向导会自动生成一个def文件,def文件属源文件。

COMPNT1.DEF

;compnt1 module-definition file

LIBRARY              Compnt1.dll

DESCRIPTION      '(C) BLABLABLA....'

EXPORTS

                               CreateInstance @1 PRIVATE

关键在EXPORTS中的内容。列出待从DLL中输出的函数的名称,对每一个名称还可以加上一个序号。

在LIBRARY行,必须写上DLL文件的名称。

DLL的装载

使用win32的LoadLibraryGetProcAddress,客户可以动态的链接到组件上。

HISTANCE LoadLibrary (

                  LPCTSTR lpLibFileName ) ;

LoadLibrary以被装载的DLL的名称作为参数并返回一个指向所装载的DLL的句柄。

GetProcAddress函数可以使用此句柄以及待调用的函数的名称,然后返回一个指向该函数的指针。

FARPROC GetProcAddress(

                     HMODULE hModule,

                     LPCSTR lpProcName);

为何可以使用DLL来实现组件?

原因在于DLL可以共享它们所链入的应用程序的地址空间。

C++使用的虚函数来实现接口,实际上也就是一个指向函数的指针列表,VTBL。组件将为虚表分配内存,并用函数地址来初始化之。要使用VTBL,也就需要客户能访问组件为其分配的内存空间。windows中,动态链接库与客户使用的是同一地址空间,因此。互相访问不成问题。

在windows中一个正在被执行的程序称为进程,每个应用程序都以单独的进程运行,每个进程有4GB的地址空间。两个进程内的地址可能是同样的值,但物理位置却不同。因为它们的内存空间不同,就好像不同大巴车上的座位号可能一样。指针并不能从一个地址空间转到另一个地址控件。

动态链接库,会驻留在所链接的应用程序的地址空间中,与EXE共享进程,即共享地址空间。也因此,DLL也被称作进程中服务器(in-process server)。

原文地址:https://www.cnblogs.com/mumuliang/p/1873487.html