首页 > 代码库 > COM组件入门(一)

COM组件入门(一)

最近需要用到COM组件的知识,看了看COM编程指南,感觉还不错,把我的学习心得记录下来。这是我根据教程写的demo

StopWatch接口实现部分,接口部分我的项目是动态库,主要源码如下:

完整demo见:http://download.csdn.net/detail/davidsu33/7750101

stopwatch.h

#pragma once

#include <Windows.h>
#include <MMSystem.h>
#include <Unknwn.h>
#include <WinBase.h>
#include "timer_i.h"

class stopwatcher
{
public:
	stopwatcher(void);
	~stopwatcher(void);
};

class IStopWatch : public IUnknown
{
public:
	//virtual unsigned long _stdcall Release() = 0;
	virtual HRESULT _stdcall Start() = 0;
	virtual HRESULT _stdcall ElaspedTime(float *elaspedtime) = 0;
};

class CStopWatch : public IStopWatch
{
public:
	CStopWatch()
	{
		m_nRefValue = http://www.mamicode.com/0;>



客户端的调用代码

#include "../stopwatch/stopwatcher.h"
#include "../stopwatch/timer_i.h"

#include <iostream>
#include <cstring>
#include <cassert>

#define TIMERDLL L"../Debug/stopwatch.dll"
#define PROCNAME "DllGetClassObject"

typedef HRESULT  (_stdcall*  GETOBJFUNC)(REFCLSID , REFIID , LPVOID* );

using namespace std;
void trace(const char *str)
{
	cout<<str<<endl;
}

void trace(const string& s)
{
	cout<<s.c_str()<<endl;
}

HRESULT CreateInstance(void **p, HMODULE *rhMod)
{
	HMODULE hMod = LoadLibrary(TIMERDLL);
	if(!hMod)
		return E_FAIL;

	GETOBJFUNC proc = 
		(GETOBJFUNC)GetProcAddress(hMod, PROCNAME);

	if(!proc)
		return E_FAIL;

	*p = proc;
	*rhMod = hMod;

	return S_OK;
}

void FreeInstance(HMODULE hMod)
{
	assert(FreeLibrary(hMod));
}

void testInstance()
{
	void *fptr = NULL;
	HMODULE hMod = NULL;
	HRESULT hr = CreateInstance(&fptr, &hMod);
	if(FAILED(hr))
	{
		trace("CreateInstace failed");
		return;
	}

	GETOBJFUNC proc = (GETOBJFUNC)(fptr);
	IUnknown *ptr = NULL;
	
	//首先得到类实例
	//然后根据类实例得到IUnknown
	//最后通过IUnknown调取QueryInterface接口来得到其子类的接口对象
	//调用子类的接口对象
	hr = proc(CLSID_CStopWatch, IID_IUnknown, (LPVOID*)&ptr);
	if(FAILED(hr))
	{
		trace("GetObject failed");
		return;
	}

	if(!ptr)
	{
		trace("ptr is null");
		return;
	}

	IStopWatch *ptrSW = NULL;
	hr = ptr->QueryInterface(IID_IStopWatch, (void**)&ptrSW);
	assert(SUCCEEDED(hr));

	hr = ptrSW->Start();
	assert(SUCCEEDED(hr));

	int m=0;
	for(int i=0; i<10000000; ++i)
		++m;

	float elaspedtime = 0;
	hr = ptrSW->ElaspedTime(&elaspedtime);
	assert(SUCCEEDED(hr));

	cout<<"ElaspedTime:"<<elaspedtime<<endl;

	//释放对象本身
	ptrSW->Release();

	FreeInstance(hMod);
}

int main(int argc, char *argv[])
{
	testInstance();
	getchar();
	return 0;
}