正在阅读:经典编程:DLL地狱及其解决方案经典编程:DLL地狱及其解决方案

2004-05-17 10:05 出处:CSDN 作者:happydeer(翻译) 责任编辑:linjixiong
现在可以看出,在DLL的导出类中增加虚函数是一个多么严重的问题!不过,如果虚函数是用来处理回调事件的,我们有办法来解决这个问题(下文有介绍)。      COM及其它      现在可以看出,DLL的向后兼容性问题是一个很出名的问题。解决这些问题,不仅可以借助于一些约定,而且可以通过其它一些先进的技术,比如COM技术。因此,如果你想摆脱“DLL Hell”问题,请使用COM技术或者其它一些合适的技术。      让我们回到我接受的那个任务(我在本文开头的地方讲到的那个任务)————解决一个使用DLL的产品的向后兼容性问题。      我对COM有些了解,因此我的第一个建议是使用COM技术来克服那个项目中的所有问题。但这个建议因为如下原因最终被否决了:   1. 那个产品已经在某个内部层中有一个COM服务器。   2. 将一大堆接口类重写到COM的形式,投入比较大。   3. 因为那个产品是DLL库,而且已经有很多应用程序在使用它了。因此,他们不想强制他们的客户重写他们的应用程序。      换句话说,我被要求完成的任务是,以最小的代价来解决这个DLL向后兼容性问题。当然,我应该指出,这个项目最主要的问题在于增加新的成员和接口类上的虚回调函数。第一个问题可以简单地通过在类声明中增加一个指向一个数据结构的指针来解决(这样可以任意增加新的成员)。这种方法我在上面已经提到过。但是第二个问题,虚回调函数的问题是新提出的。因此,我提出了下面的最小代价、最有效的解决方法。      虚回调函数与继承      然我们想象一下,我们有一个DLL,它导出了几个类;客户应用程序会从这些导出类派生新的类,以实现虚函数来处理回调事件。我们想在DLL中做一个很小的改动。这个改动允许我们将来可以给导出类“无痛地”增加新的虚回调函数。同时,我们也不想影响使用当前版本DLL的应用程序。我们期望的就是,这些应用程序只有在不得已的时候才协同新版本的DLL进行一次重新编译。因此,我给出了下面的解决方案:      我们可以保留DLL导出类中的每个虚回调函数。我们只需记住,在任何一个类定义中增加一个新的虚函数,如果应用程序不协同新版本的DLL重新编译,将导致严重的问题。我们所做的,就是想要避免这个问题。这里我们可以一个“监听”机制。如果在DLL导出类中定义并导出的虚函数被用作处理回调,我们可以将这些虚函数转移到独立的接口中去。      让我们来看下面的例子:      // 如果想要测试改动过的DLL,请将下面的定义放开   //#define DLL_EXAMPLE_MODIFIED      #ifdef DLL_EXPORT    #define DLL_PREFIX __declspec(dllexport)   #else    #define DLL_PREFIX __declspec(dllimport)   #endif      /********** DLL的导出类 **********/   #define CLASS_UIID_DEF static short GetClassUIID(){return 0;}   #define OBJECT_UIID_DEF virtual short    GetObjectUIID(){return this->GetClassUIID();}      // 所有回调处理的基本接口   struct DLL_PREFIX ICallBack   {    CLASS_UIID_DEF    OBJECT_UIID_DEF   };      #undef CLASS_UIID_DEF      #define CLASS_UIID_DEF(X) public: static    short GetClassUIID(){return X::GetClassUIID()+1;}      // 仅当DLL_EXAMPLE_MODIFIED宏已经定义的时候,进行接口扩展   #if defined(DLL_EXAMPLE_MODIFIED)   // 新增加的接口扩展   struct DLL_PREFIX ICallBack01 : public ICallBack   {    CLASS_UIID_DEF(ICallBack)    OBJECT_UIID_DEF    virtual void DoCallBack01(int event) = 0; // 新的回调函数   };
察看评论详细内容 我要发表评论
作者笔名 简短内容 发表时间
:
键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品