DLL中类的显式链接

DLL中类的显式链接

ID:38363795

大小:208.50 KB

页数:22页

时间:2019-06-11

DLL中类的显式链接_第1页
DLL中类的显式链接_第2页
DLL中类的显式链接_第3页
DLL中类的显式链接_第4页
DLL中类的显式链接_第5页
资源描述:

《DLL中类的显式链接》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、DLL中类的显式链接2008-03-1400:33    DLL的显式链接在某些时候比隐式链接具有更大的灵活性。比如,如果在运行时发现DLL无法找到,程序可以显示一个错误信息并能继续运行。当你想为你的程序提供插件服务时,显式链接也很有用处。显式链接到全局C/C++函数非常简单。假设你想调用DLL中的一个函数ExportedFn,你可以像这样很简单地导出它:extern"C"_declspec(dllexport)voidExportedFn(intParam1,char*param2);必须使用extern"C"链

2、接标记,否则C++编译器会产生一个修饰过的函数名,这样导出函数的名字将不再是ExportedFn,而是一个形如"??ExportedFn@QAEX”的名字。假设这个函数从DLL1.dll导出,那么客户端可以像这样调用这个函数:HMODULEhMod=LoadLibrary("Dll1.dll");typedefvoid(*PExportedFn)(int,char*);PExportedFnpfnEF=(PExportedFn)GetProcAdress("ExportedFn");pfnEF(1,"SomeStr

3、ing");如果你想导出并显式链接一组C++成员函数又该怎么办呢?这里有两个问题。第一是C++成员函数名是经过修饰的(即使指定extern"C"标记也是这样);第二是C++不允许将指向成员函数的指针转换成其它类型。这两个问题限制了C++类的显式链接。下面介绍两种方法来解决这个问题:①用虚函数表的方法,这也是COM使用的方法;②用GetProcAddress直接调用。我将以下面这个类为例进行讲解:classA{private:intm_nNum;   public:  A();A(intn);virtual~A();

4、voidSetNum(intn);intGetNum();};一.用虚函数表进行显式链接这个方法是COM的基础。当我们定义一组虚函数的时候,编译器会创建一个虚函数表,将各虚函数的地址按声明的顺序放入其中。当一个类对象被创建时,它的前四个字节是一个指针,指向这个虚函数表。如果我们将A的定义修改成这样:classA{private:intm_nNum;         public:        A();A(intn);virtual~A();virtualvoidSetNum(intn);virtualintGet

5、Num();};那么一个虚函数表将被编译器创建出来,其中包含三个函数的地址:析构函数,SetNum和GetNum。现在类对象要在dll中创建。既然我们要显式链接,就需要一些全局导出函数来调用operatornew以创建对象。因为A有两种构造函数,所以我们定义两个函数CreateObjectofA()和CreateObjectofA1(int)并将其导出。客户可以这样来使用类对象:typedefA*(*PFNCreateA1)();PFNCreateA1pfnCreateA1=(PFNCreateA1)GetProc

6、Address(hMod,TEXT("CreateObjectofA1"));A*a=(pfnCreateA1)();a->SetNum(1);_tprintf(TEXT("Valueofm_nNuminais%d"),a->GetNum());deletea;要注意的是CreateObjectofA必须使用operatornew来创建对象这样客户端才可以安全地调用operatordelete来销毁对象:extern"C"__declspec(dllexport)A*CreateObjectofA1(){ret

7、urnnewA();}这个方法的使用得用户可以很容易地为你的程序制作插件。它的缺点是创建对象的内存必须在dll中分配。二.直接使用GetProcAddress进行显式链接这个方法的关键在于将GetProcAddress函数返回的FARPROC类型转化为C++中指向成员函数的指针。幸运的是,通过C++的unio和模板机制,这个目标可以很容易地实现。我们要做的只是定义如下的函数:templateDestforce_cast(Srcsrc){union{Destd;Srcs;}co

8、nvertor;convertor.s=Src;returnconvertor.d;}上面的函数允许我们在任何类型间进行转换,比reinterpret_cast更加有效。例如,我们定义一种指针类型:typedefvoid(A::*PSetNum)(int);我们可以将FARPROC类型的指针fp转化成PSetNum:PSetNumpsn=force_cast

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。