65.9K
CodeProject 正在变化。 阅读更多。
Home

包含示例

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (12投票s)

2006 年 6 月 20 日

2分钟阅读

viewsIcon

37571

downloadIcon

328

容器概念的说明。

引言

在尝试学习 COM 中可应用的重用机制时,我在网上搜索了很长时间,希望能找到一个关于容器的非常简单的示例,作为入门。我找到了很多关于容器的理论,但没有找到任何简单的示例。考虑到初学者,我将尝试解释实现容器涉及的步骤。我不是一个好的技术写作者,但我会尽力而为。

定义

容器是一种重用机制。在这个重用过程中,外部组件充当客户端和内部组件之间的中介,以委托调用。这种机制确保内部组件的接口不会直接暴露给客户端。

我们将构建一个 ComplexCalculator 组件,通过其接口暴露 AddMultiply 功能。 存在一个名为“Calculator”的现有组件,它通过其接口 ISimpelMath 暴露一个“Add”方法。 您可以从上面的链接下载 Calculator。 我想:为什么还要编写代码来获取现有的功能“Add”呢? 因此,我们将使用现有的组件 Calculator 开发一个新的组件 ComplexCalculator

现在,我们只需要担心“Multiply”了。

步骤

  • 创建一个新的 ATL 项目,命名为“ComplexCalculator”,并选择类型为 DLL。
  • 插入一个新的 ATL 对象,命名为“ComplexMath”,然后单击“确定”。
  • 选择“类向导”选项卡,右键单击 IComplexMath,然后选择“添加方法”。
    Method Name: Mul
    Parameters: [in] long a, [in] long b, [out, retval] long* result
  • 添加以下代码
    STDMETHODIMP CComplexMath:: Mul (long a, long b, long *result)
    {
        *result = a * b;
        return S_OK;
    }
  • 选择“类向导”选项卡,右键单击 CComplexMath,然后选择“实现接口”。
  • 单击“添加类型库”按钮->浏览,选择 Calculator.tlb,然后单击打开
  • 打开 ComplexCalculator.idl 文件并进行以下更改

    更改以粗体字母表示。

    library COMPLEXCALCULATORLib
    {
        importlib("stdole32.tlb");
        importlib("stdole2.tlb");
        import "Calculator.idl";
        //import the Calculator’s IDL file.
        //If not present in local dir, specify the path.
        [
            uuid(FB30F62F-4DF3-47CD-A67F-50E0CF7C7B67),
            helpstring("ComplexMath Class")
        ]
        coclass ComplexMath
        {
            [default] interface IComplexMath;
            interface ISimpleMath;
            //Add the interface name to the coclass
            //so that it can be exposed to the client.
        };
    };
  • 打开 ComplexMath.h 文件并添加以下代码

    outerCOM (ComplexMath) 创建一个 innerCOM (SimpleMath) 的对象。

    ISimpleMath* SimpleMathptr;
    
    //Override the FinalConstruct to get the 
    //interface pointer of the Inner Component.
    HRESULT FinalConstruct()
    {
             return CoCreateInstance(__uuidof(SimpleMath),NULL,
                                      CLSCTX_INPROC_SERVER,
                                     __uuidof(ISimpleMath),
                                     (void**)&SimpleMathptr);
    }
    void FinalRelease()
    {
        SimpleMathptr->Release();
    }
  • ComplexMath.h 中的 Add 方法代码更改如下

    这就是 outerCOM (ComplexMath) 将调用委托给 innerCOM (SimpleMath) 的方式。

    STDMETHOD(Add)(LONG a, LONG b, LONG * result)
    {
            SimpleMathptr->Add(a,b,result);
            return S_OK;
    }

就这样了……

外部组件包含内部组件对象。 用户感觉好像在使用 ComplexCalculator,即使他们查询的是 SimpleMath 接口。

让我们快速构建一个客户端,并确保容器关系正常工作。

客户端

创建一个基于对话框的 MFC 应用程序,并在对话框上放置一个按钮。 在 StdAfx.h 中,添加以下内容

#import "ComplexCalculator.tlb"
// If this is not present in the current dir, specify the path.

将以下代码添加到 OnButton 事件

using namespace COMPLEXCALCULATORLib;
void CContainmentClientDlg::OnButton1() 
{
        CoInitialize(NULL);
        CString str;
        long res1;
        IComplexMathPtr objComplex(__uuidof(ComplexMath));
             //Use the smart
             //pointer to get  
             //ComplexMath

    res1=objComplex->Mul(10,20);
    str.Format("Mul is=%d",res1);
    AfxMessageBox(str);

    ISimpleMathPtr objSimple;
    objSimple=objComplex;  //Use the assignment operator on the
                           //smart Pointer which will take care of 
                           //query interface to SimpleMath interface.
    long m = objSimple->Add(10,20);
    str.Format("Add of 10,20 is=%d",m);
    AfxMessageBox(str);
    objComplex=NULL;
    objSimple=NULL;

    CoUninitialize();
}

在使用源代码之前,请注册 DLL。

© . All rights reserved.