1.组件中必须有3个函数,QueryInterface、AddRef、Release,它们3个函数也组成一个接口,叫"IUnknown"。
2.组件API及接口指针中,除了IUnknown::AddRef()和IUnknown::Release()两个函数外,其它所有的函数,都以 HRESULT 作为返回值。
3.原则:COM 组件是运行在分布式环境中的。通俗地说,你不能直接把一个内存指针直接作为参数传递给COM函数。
4.结果判断一般用VC提供的宏:
HRESULT hr = 调用组件函数;
if( SUCCEEDED( hr ) ){...} // 如果成功
if( FAILED( hr ) ){...} // 如果失败
5.Browser Helper Objects,我译为"浏览器帮助者对象",以下皆简称BHO
==================================
如果感觉不清楚,请先参看com组件应用(1),因为范例是从上例中改造过来的。
还是用具体范例来讲:computer_def.h
#include
<
Unknwn.h
>
#define
UUID_ICOMPUTER __declspec( uuid( "9DC95DDC-FF98-4afe-B17E-42F028E34F68" ) )
class
UUID_ICOMPUTER Icomputer:
public
IUnknown
{
public
:
virtual
int
add(
int
a,
int
b )
=
0
;
};
#define
UUID_ICOMPUTEREX __declspec( uuid( "3B8BF613-7AF1-4672-9EC3-E5DC49A6E8D9" ) )
class
UUID_ICOMPUTEREX IcomputerEx:
public
IUnknown
{
public
:
virtual
int
sub(
int
a,
int
b )
=
0
;
};
实现类:
class
Ccomputer :
public
Icomputer,
public
IcomputerEx
{
public
:
virtual
HRESULT STDMETHODCALLTYPE QueryInterface(
/*
[in]
*/
REFIID riid,
/*
[iid_is][out]
*/
void
__RPC_FAR
*
__RPC_FAR
*
ppvObject)
{
if
(riid
==
__uuidof(Icomputer))
{
*
ppvObject
=
(Icomputer
*
)(
this
);
}
else
if
(riid
==
__uuidof(IcomputerEx))
{
*
ppvObject
=
(IcomputerEx
*
)(
this
);
}
return
S_OK;
}
virtual
ULONG STDMETHODCALLTYPE AddRef(
void
)
{
m_nRef
++
;
return
m_nRef;
}
virtual
ULONG STDMETHODCALLTYPE Release(
void
)
{
m_nRef
--
;
if
(
0
==
m_nRef)
{
delete
this
;
}
return
0
;
}
virtual
int
add(
int
a,
int
b)
{
return
a
+
b;
}
virtual
int
sub(
int
a,
int
b)
{
return
a
-
b;
}
private
:
ULONG m_nRef;
};
使用上:
Icomputer
*
pComputer;
IcomputerEx
*
pComputerEx;
HMODULE hDll
=
::LoadLibrary(TEXT(
"
computer.dll
"
));
typedef HRESULT (__stdcall
*
PFN_DllGetClassObject)(Icomputer
**
ppv);
PFN_DllGetClassObject pDllGetClassObject
=
(PFN_DllGetClassObject)::GetProcAddress(hDll,
"
DllGetClassObject
"
);
if
(NULL
==
pDllGetClassObject)
{
//
nRet = STATUS_SEVERITY_ERROR;
}
//
创建接口
HRESULT hRet
=
pDllGetClassObject(
&
pComputer);
if
(FAILED(hRet))
{
//
nRet = STATUS_SEVERITY_ERROR;
}
……
int
iRet
=
pComputer
->
add(iNum_1,iNum_2);
pComputer
->
QueryInterface(__uuidof(IcomputerEx),(
void
**
)
&
pComputerEx);
//
pComputerEx = (pComputerEx)(pC);
iRet
=
pComputerEx
->
sub(iNum_1,iNum_2);
阐述总结:继承IUnknown 接口,实现其中方法。 这样就可以通过QueryInterface 来查询接口,并使用其中的函数。