1.实现一个COM组件
1.)使用VC6建立Win32 Dll工程
2.)定义接口
interface IX : public IUnknown
{
virtual HRESULT __stdcall FunX()=0;
};
interface IY : public IUnknown
{
virtual HRESULT __stdcall FunY()=0;
};
interface IZ : public IUnknown
{
virtual HRESULT __stdcall FunZ()=0;
};
extern "C" const CLSID CLSID_CA =
{ 0xd7153f69, 0x9668, 0x47d7,
{ 0xb9, 0xc8, 0xb2, 0x1a, 0x2b, 0xbe, 0xc5, 0x44 } };
// {2F8AD6CD-E631-4120-8F72-23C5E96921DE}
extern "C" const IID IID_IX =
{ 0x2f8ad6cd, 0xe631, 0x4120,
{ 0x8f, 0x72, 0x23, 0xc5, 0xe9, 0x69, 0x21, 0xde } } ;
// {B6985A8F-6EA0-4a58-B3DC-9E14BCB81041}
extern "C" const IID IID_IY =
{ 0xb6985a8f, 0x6ea0, 0x4a58,
{ 0xb3, 0xdc, 0x9e, 0x14, 0xbc, 0xb8, 0x10, 0x41 } };
// {311FD901-390D-4fe1-AE83-96176D0A1991}
extern "C" const IID IID_IZ =
{ 0x311fd901, 0x390d, 0x4fe1,
{ 0xae, 0x83, 0x96, 0x17, 0x6d, 0xa, 0x19, 0x91 }};
{
virtual HRESULT __stdcall FunX()=0;
};
interface IY : public IUnknown
{
virtual HRESULT __stdcall FunY()=0;
};
interface IZ : public IUnknown
{
virtual HRESULT __stdcall FunZ()=0;
};
extern "C" const CLSID CLSID_CA =
{ 0xd7153f69, 0x9668, 0x47d7,
{ 0xb9, 0xc8, 0xb2, 0x1a, 0x2b, 0xbe, 0xc5, 0x44 } };
// {2F8AD6CD-E631-4120-8F72-23C5E96921DE}
extern "C" const IID IID_IX =
{ 0x2f8ad6cd, 0xe631, 0x4120,
{ 0x8f, 0x72, 0x23, 0xc5, 0xe9, 0x69, 0x21, 0xde } } ;
// {B6985A8F-6EA0-4a58-B3DC-9E14BCB81041}
extern "C" const IID IID_IY =
{ 0xb6985a8f, 0x6ea0, 0x4a58,
{ 0xb3, 0xdc, 0x9e, 0x14, 0xbc, 0xb8, 0x10, 0x41 } };
// {311FD901-390D-4fe1-AE83-96176D0A1991}
extern "C" const IID IID_IZ =
{ 0x311fd901, 0x390d, 0x4fe1,
{ 0xae, 0x83, 0x96, 0x17, 0x6d, 0xa, 0x19, 0x91 }};
3.)实现接口 IX,IY
class CA : public IX,public IY
{
public:
CA();
virtual ~CA();
public:
// Interface : IUnknown
virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
virtual ULONG __stdcall AddRef() ;
virtual ULONG __stdcall Release() ;
// Interface : IX
virtual HRESULT __stdcall FunX();
// Interface : IY
virtual HRESULT __stdcall FunY();
private:
long m_lnRef ;
};
CA::CA()
{
m_lnRef = 1 ;
InterlockedIncrement(&g_lnClsRef) ;
}
CA::~CA()
{
InterlockedDecrement(&g_lnClsRef) ;
}
HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<IX *>(this) ;
}
else if(iid == IID_IX)
{
*ppv = static_cast<IX *>(this) ;
}
else if(iid == IID_IY)
{
*ppv = static_cast<IY *>(this) ;
}
else
{
*ppv = NULL ;
return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK ;
}
ULONG __stdcall CA::AddRef()
{
return InterlockedIncrement(&m_lnRef) ;
}
ULONG __stdcall CA::Release()
{
if (InterlockedDecrement(&m_lnRef) == 0)
{
delete this ;
return 0 ;
}
return m_lnRef ;
}
{
public:
CA();
virtual ~CA();
public:
// Interface : IUnknown
virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
virtual ULONG __stdcall AddRef() ;
virtual ULONG __stdcall Release() ;
// Interface : IX
virtual HRESULT __stdcall FunX();
// Interface : IY
virtual HRESULT __stdcall FunY();
private:
long m_lnRef ;
};
CA::CA()
{
m_lnRef = 1 ;
InterlockedIncrement(&g_lnClsRef) ;
}
CA::~CA()
{
InterlockedDecrement(&g_lnClsRef) ;
}
HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<IX *>(this) ;
}
else if(iid == IID_IX)
{
*ppv = static_cast<IX *>(this) ;
}
else if(iid == IID_IY)
{
*ppv = static_cast<IY *>(this) ;
}
else
{
*ppv = NULL ;
return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK ;
}
ULONG __stdcall CA::AddRef()
{
return InterlockedIncrement(&m_lnRef) ;
}
ULONG __stdcall CA::Release()
{
if (InterlockedDecrement(&m_lnRef) == 0)
{
delete this ;
return 0 ;
}
return m_lnRef ;
}
4.)实现IClassFactory
class CFactory : public IClassFactory
{
public:
CFactory();
virtual ~CFactory();
public:
// Interface : IUnknown
virtual HRESULT __stdcall QueryInterface(
{
public:
CFactory();
virtual ~CFactory();
public:
// Interface : IUnknown
virtual HRESULT __stdcall QueryInterface(
const IID& iid,
void** ppv
) ;
virtual ULONG __stdcall AddRef() ;
virtual ULONG __stdcall Release() ;
// Interface : IClassFactory
virtual HRESULT __stdcall CreateInstance(
IUnknown* pUnknownOuter,
const IID& iid,
void** ppv
) ;
virtual HRESULT __stdcall LockServer(BOOL bLock) ;
private:
long m_lnRef ;
};
CFactory::CFactory()
{
m_lnRef = 1 ;
}
CFactory::~CFactory()
{
}
// Interface : IUnknown
HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
{
if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
{
*ppv = static_cast<IClassFactory*>(this) ;
}
else
{
*ppv = NULL ;
return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
return S_OK ;
}
ULONG __stdcall CFactory::AddRef()
{
return InterlockedIncrement(&m_lnRef) ;
}
ULONG __stdcall CFactory::Release()
{
if (InterlockedDecrement(&m_lnRef) == 0)
{
delete this ;
return 0 ;
}
return m_lnRef ;
}
// Interface : IClassFactory
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
CA * pA = new CA ;
if(pA == NULL)
{
return E_OUTOFMEMORY ;
}
HRESULT hRet = pA->QueryInterface(iid,ppv);
pA->Release();
return hRet ;
}
HRESULT __stdcall CFactory::LockServer(BOOL bLock)
{
if (bLock)
{
InterlockedIncrement(&g_lnFacRef) ;
}
else
{
InterlockedDecrement(&g_lnFacRef) ;
}
return S_OK ;
}
5.)实现注册类
代码见附件.
6.)导出接口函数
STDAPI DllGetClassObject(
const CLSID& clsid,
const IID& iid,
void** ppv
const IID& iid,
void** ppv
)
{
if (clsid != CLSID_CA)
{
return CLASS_E_CLASSNOTAVAILABLE ;
}
CFactory* pFactory = new CFactory ;
if (pFactory == NULL)
{
return E_OUTOFMEMORY ;
}
HRESULT hRet = pFactory->QueryInterface(iid, ppv) ;
pFactory->Release() ;
return hRet ;
}
STDAPI DllCanUnloadNow()
{
if(g_lnClsRef == 0 && g_lnFacRef == 0)
{
return S_OK ;
}
else
{
return S_FALSE ;
}
}
//== Register Info===============================
LPCTSTR g_ptszName = _T("PENGY Test Com.");
LPCTSTR g_ptszVerIndProgID = _T("PENGY.Test");
LPCTSTR g_ptszProgID = _T("PENGY.Test.1");
//== Register Info===============================
STDAPI DllRegisterServer()
{
TCHAR pszPath[1024];
if(0 == GetModuleFileName(g_hmodSelf,pszPath,1024))
{
return S_FALSE ;
}
// 将相关信息写入注册表.
return CRegisterAPI::RegisterServer(
pszPath,
CLSID_CA,
g_ptszName,
g_ptszVerIndProgID,
g_ptszProgID
) ;
}
STDAPI DllUnregisterServer()
{
// 删除相关的注册信息
return CRegisterAPI::UnregisterServer(
CLSID_CA,
g_ptszVerIndProgID,
g_ptszProgID
) ;
}
{
if (clsid != CLSID_CA)
{
return CLASS_E_CLASSNOTAVAILABLE ;
}
CFactory* pFactory = new CFactory ;
if (pFactory == NULL)
{
return E_OUTOFMEMORY ;
}
HRESULT hRet = pFactory->QueryInterface(iid, ppv) ;
pFactory->Release() ;
return hRet ;
}
STDAPI DllCanUnloadNow()
{
if(g_lnClsRef == 0 && g_lnFacRef == 0)
{
return S_OK ;
}
else
{
return S_FALSE ;
}
}
//== Register Info===============================
LPCTSTR g_ptszName = _T("PENGY Test Com.");
LPCTSTR g_ptszVerIndProgID = _T("PENGY.Test");
LPCTSTR g_ptszProgID = _T("PENGY.Test.1");
//== Register Info===============================
STDAPI DllRegisterServer()
{
TCHAR pszPath[1024];
if(0 == GetModuleFileName(g_hmodSelf,pszPath,1024))
{
return S_FALSE ;
}
// 将相关信息写入注册表.
return CRegisterAPI::RegisterServer(
pszPath,
CLSID_CA,
g_ptszName,
g_ptszVerIndProgID,
g_ptszProgID
) ;
}
STDAPI DllUnregisterServer()
{
// 删除相关的注册信息
return CRegisterAPI::UnregisterServer(
CLSID_CA,
g_ptszVerIndProgID,
g_ptszProgID
) ;
}
7.)编译生成ComServer.dll
8.)注册和卸载
注册:regsvr32 ComServer.dll
卸载:regsvr32 /u ComServer.dll
9.)完成
2. 实现一个COM客户程序
1.)初始化COM
CoInitialize(NULL);
2.)创建COM对象
IUnknown * pIUnknown = NULL ;
CoCreateInstance(
CLSID_CA, // 类ID
NULL, // 聚合时使用
CLSCTX_INPROC_SERVER, // 组件类别(进程内组件)
IID_IUnknown,
(void**)& pIUnknown
);
CoCreateInstance(
CLSID_CA, // 类ID
NULL, // 聚合时使用
CLSCTX_INPROC_SERVER, // 组件类别(进程内组件)
IID_IUnknown,
(void**)& pIUnknown
);
3.)查询接口并使用接口提供的功能
IX * pIX = NULL ;
HRESULT hRet = pIUnknown->QueryInterface(IID_IX,(void**)&pIX);
if(SUCCEEDED(hRet))
{
pIX->FunX() ;
// …
pIX->Release();
}
HRESULT hRet = pIUnknown->QueryInterface(IID_IX,(void**)&pIX);
if(SUCCEEDED(hRet))
{
pIX->FunX() ;
// …
pIX->Release();
}
4.)卸载COM库
CoUninitialize();
转载于:https://blog.51cto.com/pyhcx/144163