首页 > 其他 > 详细

COM专题四---实现COM接口(implement COM Interface)

时间:2014-04-25 21:14:26      阅读:785      评论:0      收藏:0      [点我收藏+]
Prerequisite:C++ 编程者,熟悉windows编程,熟悉Win32 Dll,了解windows注册表。

作者:收割者

本篇文章讲解如何实现COM接口,一方面我们可以实现COM的预定义接口,也就是系统中微软提供的接口,例如,IDataObject接口,这个接口是在实现拖放,剪切板(新的剪切板技术)的时候,需要我们实现的接口;另一方面,我们可以实现我们自定义的COM接口,但是自定义的COM接口应该在实现之前选择一种接口的驱动方式,如类型库(TypeLib)还是代理根服务器(proxy/sub dll),并实现这些驱动方式,在系统中注册,前面文章我用了代理根服务器的方式在系统中注册了我定义的接口。本篇文章,我继续上面一篇文章,实现自定义的COM接口。

我们将接口的定义视为类似于定义纯虚函数的过程。那么现在对接口进行实现(由Implement翻译过来),就相当于重写虚函数,纯虚函数只有函数的原型,没有实现,接口也是,接口的定义只是声明了它的方法的原型。要使用它,需要实现它,另外,接口的实现可以多次实现,不用在意原有的实现。接着上一篇文章,在解决方案中添加一个新的项目,在“解决方案视图”中,点击鼠标右键,弹出快捷菜单,选择“添加”,选择“新建项目”。如下图:

bubuko.com,布布扣

在“已安装模板中”,选择Win32项目,填写名称,我这里是ImplCom,设置项目的属性,设置为DLL,选中“空项目”.如下图:

bubuko.com,布布扣

bubuko.com,布布扣

现在项目里面是空的,我们添加一个源文件,DllMain,添加DllMain入口点代码,这个代码在msdn中有,直接复制过来就可以了。在“解决方案视图”中ImplCom项目名称上,点击右键,在快捷菜单中,选中“添加”,选中“新建项”,在弹出来的对话框中,选中cpp文件,添加名称,如下图:

bubuko.com,布布扣

bubuko.com,布布扣

bubuko.com,布布扣

上面图中DllMain入口点函数的内容,在msdn讲解DLL中关于DllMain入口点的时候,有现成的代码,直接复制过来就可以了,在以后,编写Win32的DLL的时候,也是这样,如果是你建立的是空项目,自己添加cpp文件之后,就从msdn中直接把入口点函数的代码复制过来就可以了。

现在我们再添加一个头文件和一个源文件用于实现接口。方法同上,在ImpleCom上点击右键......。完成之后,如下图:

bubuko.com,布布扣

我添加了Reaper.h,Reaper.cpp文件。现在编写实现接口的代码,首先在Reaper.h文件中,代码如下:

#pragma once

#include "C:\\Users\\Administrator\\Documents\\Visual Studio 2010\\Projects\\COMSample\\COMSample\\COMSampleInterface_h.h"
#include "Shlwapi.h"
#pragma comment(lib,"Shlwapi.lib")

class CReaper:public IShowGeZhe
{
public:
	CReaper();
private:
	~CReaper();
private:
	LONG m_cRef;
public:
	/////////////////////IUnknown接口的方法
	STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();
	//////////////////////IShowGeZhe接口的方法
	STDMETHODIMP ShowHelloCOM(HWND hwnd);
};
COMSampleInterface_h.h文件就是我们在定义接口的时候生成的四个文件之一(参考我的博客文章“COM专题三”).当中它声明了接口及接口方法的原型。这里我们要实现它,因此包含它,我这里使用的全路径,你可以使用相对路径或是将这个头文件复制到你当前的项目目录下,那么就直接用#include "COMSampleInterface_h.h"就可以了。Shlwapi.h头文件是一个系统头文件,属于Shell编程部分的,主要是提供帮助函数(helper function),后面会用到QISearch函数,这个函数在这个文件中声明。

所有的COM接口都必须直接或是间接的继承IUnknown接口,这个接口有三个方法,用管理COM对象的生命周期和接口的询问(query)。IShowGeZhe这个接口就是我们定义的接口,只有一个方法ShowHelloCOM。

接着我们在源文件Reaper.cpp中编写实现代码:

#include "Reaper.h"
/////////////构造函数和析构函数
extern long   g_cDllRef;
CReaper::CReaper()
{
	///////在这里初始化项目
	m_cRef=1;
	g_cDllRef++;
}

CReaper::~CReaper()
{
	/////
	g_cDllRef--;
}

HRESULT CReaper::QueryInterface(REFIID riid, void **ppv)
{
	static QITAB rgqit[] = 
    {   
        QITABENT(CReaper,IShowGeZhe),
        { 0 }
    };
    return QISearch(this, rgqit, riid,ppv);
}
ULONG CReaper::AddRef()
{
	  return InterlockedIncrement(&m_cRef);
}
ULONG CReaper::Release()
{
	 ULONG uCount = InterlockedDecrement(&m_cRef);
    if (uCount == 0)
    {
        delete this;
    }
    return uCount;

}
HRESULT CReaper::ShowHelloCOM(HWND hwnd)
{
	MessageBox(hwnd,L"收割者COM测试",L"TIP",MB_OK);
	return S_OK;
}

有关g_cDllRef这里暂不做讨论,在后面将COM组件注册的时候说明。在构造函数中,m_cRef引用计数(reference count)赋为1.引用计数用来控制COM对象的生命周期,当引用计数到0的时候,就会自动删除对象,它代表了这个COM对象的接口被引用了多少次,这也是为什么我们在使用COM接口的时候,当不需要那个接口的时候会调用Release方法,它会减少一个引用数,当接口复制给另外一个接口指针的时候,就会调用AddRef,它会增加一个引用计数。QueryInterface方法的作用就是将接口公开给调用者,同时自动调用一次AddRef,所以我们通过QueryInterface之后,我们不用调用AddRef。InterlockedIncrement(对引用数增加1),InterlockedDecrement(引用数减去1),QISearch(找到接口的偏移地址)都是帮助函数。对于IUnknown接口方法的编写了是固定的,如果说有变化,那就是QueryInterface中,一个COM对象可以支持多个接口。写法上就有点区别。

HRESULT CReaper::QueryInterface(REFIID riid, void **ppv)
{
	static QITAB rgqit[] = 
    {   
        QITABENT(CReaper,IShowGeZhe), 
        QITABENT(CRpaper,I*****),//别的接口
       { 0 } 
    };
return QISearch(this, rgqit, riid,ppv);
}


实现了IUnknown方法之后,我们就可以实现我们自己的接口的方法了。这里是ShowHelloCOM。我们也已经实现了,就是简单的弹出一个对话框。

现在就完成了COM接口的实现,下一篇,将讲解实现IClassFactory接口,如果要使用如CreateInstance这样的函数获取COM接口,就应该实现这个接口,这也是获取COM接口,初始化COM对象的标准方法。在完成COM组件编写的所有的过程结束之后,会把完整的项目代码附上!

本文如果出现在除CSDN或是磐实(Pansy)之外的网站,均为非法盗用。

推荐阅读地址(磐实Pansy):http://www.panshy.com/article/Sort_Desktop/other/2014-04-25/2488.php







COM专题四---实现COM接口(implement COM Interface),布布扣,bubuko.com

COM专题四---实现COM接口(implement COM Interface)

原文:http://blog.csdn.net/xinzhiyounizhiyouni/article/details/24478989

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!