编写一个简单的COM组件

(1) 用MIDL编写.idl文件

//将以下代码保存成 IXIYIZ.idl 文件

//在命令行上进行编译,编译命令:

//midl IXIYIZ.idl

//生成 IXIYIZ.h ,dlldata.c, IXIYIZ.h, IXIYIZ_p.c

//其中 IXIYIZ.h,IXIYIZ.h 文件是我们目前所需要的

import "unknwn.idl";

[

    object,

    uuid(7F67119B-1E09-4d4f-B472-2106CCAE3275)

]

interface IX: IUnknown

{

    [local]

    void __stdcall Fx();

};

[

    object,

    uuid(A667947B-714A-4bde-B2DD-C090928D62FF)

]

interface IY: IUnknown

{

    [local]

    void __stdcall Fy();

};

[

    object,

    uuid(AA80F229-0809-4c69-B8AA-BB6F58DBC304)

]

interface IZ: IUnknown

{

    [local]

    void __stdcall Fz();

};

 

(2) 编写组件类的头文件

// 将以下代码保存成 CA.h

// 注意将(1)中生成的 IXIYIZ.h 头文件包含进来

#include<iostream>

#include"IXIYIZ.h"

using namespace std;

class CA : public IX, public IY

{

    HRESULT __stdcall QueryInterface(const IID& iid, void ** ppv);

    ULONG __stdcall AddRef(){return 0;}

    ULONG __stdcall Release(){return 0;}

    

    void __stdcall Fx(){cout<<"Fx"<<endl;}

    void __stdcall Fy(){cout<<"Fy"<<endl;}

};

extern "C" __declspec(dllexport) IUnknown* __cdecl CreateInstance();

 

(3) 编写组件类的实现文件

//将以下代码保存成 CA.cpp

//3.1编译 IXIYIZ_i.c,编译命令:

//cl /c IXIYIZ_i.c 生成 IXIYIZ_i.obj 文件

//3.2编译 CA.h 文件,编译命令:

//cl /c /GX CA.cpp 生成 CA.obj 文件

//3.3链接上面两个文件,生成组件DLL,编译命令:

//link /dll CA.obj IXIYIZ_i.obj 生成 CA.lib 和 CA.dll

//3.4将 IXIYIZ_i.obj 整合到 CA.lib 文件中,命令:

// lib CA.lib IXIYIZ_i.obj

#include"CA.h"

HRESULT __stdcall CA::QueryInterface(const IID& iid, void ** ppv)

{

    if(iid == IID_IUnknown)

    {

        cout<<"QueryInterface:Return pointer to IUnknown."<<endl;

        *ppv = static_cast<IX *>(this);

    }

    else if(iid == IID_IX)

    {

        cout<<"QueryInterface:Return pointer to IX."<<endl;

        *ppv = static_cast<IX *>(this);

    }

    else if(iid == IID_IY)

    {

        cout<<"QueryInterface:Return pointer to IY."<<endl;

        *ppv = static_cast<IY *>(this);

    }

    else

    {

        cout<<"QueryInterface:Interface not supported."<<endl;

        *ppv = NULL;

        return E_NOINTERFACE;

    }

    reinterpret_cast<IUnknown*>(*ppv)->AddRef();

    return S_OK;

}

extern "C" __declspec(dllexport) IUnknown* __cdecl CreateInstance()

{

    IUnknown *pI = static_cast<IX*>(new CA);

    pI->AddRef();

    return pI;

}


(4) 编写客户端,对(3)生成的组件(CA.dll)进行测试

//将以下代码保存成 client.cpp 文件

//4.1编译客户端,编译命令:

//cl /c /GX client.cpp 生成 client.obj 文件

//4.2链接客户端与组件,命令:

//link client.obj CA.lib

#include<iostream>

#include<unknwn.h>

#include"IXIYIZ.h"

using namespace std;

extern "C" __declspec(dllexport) IUnknown* __cdecl CreateInstance();

int main()

{

    HRESULT hr;

    cout<<"Client: Get an IUnknown pointer."<<endl;

    IUnknown* pI = CreateInstance();

    cout<<"Client: Get Interface IX."<<endl;

    IX *pIX = NULL;

    hr = pI->QueryInterface(IID_IX, reinterpret_cast<void **>(&pIX));

    if(SUCCEEDED(hr))

    {

        cout<<"Client: Succeeded getting IX."<<endl;

        pIX->Fx();

    }

    return 0;

}
原文地址:https://www.cnblogs.com/a-ray-of-sunshine/p/3416062.html