COM 구성 요소 수신기 구현(DLL, Custom)

4580 단어 COM
1 수신기 인터페이스 프로젝트의 창설
수신기는 ATL로 프로젝트를 만들고 인터페이스 함수를 추가하며 컴파일할 수 있는 마이크로컴파일 서버입니다.프로젝트 헤드 파일 "xxx.h"와 인터페이스 ID를 유지하면 됩니다.
이 예에서는 ISink Server라는 프로젝트와 ISink라는 인터페이스를 만들고 인터페이스 방법인test2(long lArg)를 추가합니다.
2 서버 생성
ATL을 사용하여 Real Server라는 서버를 만들고(DLL 선택), 인터페이스 Ireal(Apartment, Custom, Aggregation(Yes), Support Connection Points)을 추가합니다.인터페이스에 메소드 테스트 1(long lArg)을 추가합니다.대상Ireal Events 연결점에 리셋 방법인 test2(long lArg)를 추가하고 연결점을 구현(Implement)합니다.
프로젝트 디렉터리에guids를 추가합니다.h, 수신기 포함 IIDISink.프로젝트 cpp의 전면 #include "guids.h"
구현된 코드(RealServerCP.h)는 다음과 같이 코드를 수정한 후 Creal에서Fire 를 호출할 수 있습니다.테스트 2야.
#ifndef _REALSERVERCP_H_
#define _REALSERVERCP_H_
#include "..\SinkServer\SinkServer.h"
EXTERN_C const IID IID_ISink;
template 
class CProxy_IRealEvents : public IConnectionPointImpl
{
public:
	HRESULT Fire_test2(LONG lArg)
	{
   		T* pT = (T*)this;
		pT->Lock();
		HRESULT ret;
	         IUnknown** pp = m_vec.begin();
	         while (pp < m_vec.end())
	         {
		         if (*pp != NULL)
		         {
				ISink *pWzdSinks = reinterpret_cast(*pp);
				ret = pWzdSinks->test2( lArg );
		         }
			pp++;
		}
		pT->Unlock();
		return ret;
	}
};
#endif

3 클라이언트 생성
MFC를 사용하여 대화상자 응용 프로그램 클라이언트를 설정합니다. 대화상자 헤더 파일 전면에 수신기 인터페이스 프로젝트 헤더 파일 #include "SinkServer\SinkServer.h"가 포함되어 있습니다.
메시지 정의 매크로 아래에 다음을 추가합니다.
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART(SinkClass, ISink)
	STDMETHOD_(HRESULT,test2)(long);
END_INTERFACE_PART(SinkClass)

대화상자 cpp 파일의 메시지 정의 매크로에 추가하기
BEGIN_INTERFACE_MAP (CClientDlg, CClientDlg)
INTERFACE_PART (CClientDlg, IID_ISink, SinkClass)
END_INTERFACE_MAP ()

수신기의 몇 가지 기본 함수와 사용자 정의 함수를 완성합니다.
ULONG FAR EXPORT CClientDlg::XSinkClass::AddRef()
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
	return pThis->ExternalAddRef();//pThis accesses enclosing class's this pointer
}
ULONG FAR EXPORT CClientDlg::XSinkClass::Release()
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
	return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CClientDlg::XSinkClass::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
    return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
HRESULT __stdcall CClientDlg::XSinkClass::test2(long lArg)
{
	METHOD_PROLOGUE(CClientDlg, SinkClass);
	CString str;
	str.Format("%d",lArg);
	AfxMessageBox(str);
    return S_OK;
}

대화상자 cpp 파일의 앞부분에 guids를 추가합니다.h는 수신기 IID 헤드 파일을 포함하는 IIDIreal 및 CLSIDReal서버 RealServer에서 가져오기:
#include "guids.h"
#include "RealServer/RealServer.h"
#include 
const IID IID_IReal = {0xA8CA226A,0x69B1,0x4D10,{0x9A,0x25,0xD0,0x71,0x96,0x0B,0xD8,0x85}};
const CLSID CLSID_Real = {0xEA9E614F,0x5EBE,0x41ED,{0x9B,0x96,0xF7,0x6D,0x37,0xB1,0xEB,0x29}};

다음에 프로그램에서 인터페이스를 호출할 수 있다.
void CClientDlg::OnOK() 
{
	// TODO: Add extra validation here
	HRESULT hr;
	IReal *IMyReal = NULL;
	hr = CoInitialize(0);
	if (SUCCEEDED(hr))
	{
		//         
		/***************************/
		/*hr = CoCreateInstance(CLSID_Real,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_IReal,
			(void**)&IMyReal);*/
		/***************************/
		IClassFactory* pIFactory = NULL;    
		hr = CoGetClassObject(CLSID_Real,                        
			CLSCTX_INPROC_SERVER,                        
			NULL,                        
			IID_IClassFactory,                        
			(void**)&pIFactory);    
		if (SUCCEEDED(hr))    
		{        
			// create the component.        
			hr = pIFactory->CreateInstance(NULL, IID_IReal, (void**)&IMyReal);        
			pIFactory->Release();    
		}
		/****************************/
	}
	ISink *IMySink = NULL;
	hr = m_xSinkClass.QueryInterface(IID_ISink,(void**)&IMySink);
	m_xSinkClass.Release();
	DWORD dwConnectID;
	hr = AfxConnectionAdvise(
		IMyReal,			// the real server
		IID_ISink,		// our sink's IID
		IMySink,			// our sink's pointer
		FALSE,			// TRUE == increment our sink object's ref count
		&dwConnectID);		// identifier for AfxConnectionUnadvise()
	IMyReal->test1(1);
	AfxConnectionUnadvise(
		IMyReal,			// the real server
		IID_ISink,		// our sink's IID
		IMySink,			// our sink's pointer
		FALSE,			// TRUE == decrement our sink object's ref count
		dwConnectID);		// identifier from AfxConnectionAdvise()
	CoUninitialize();
}

좋은 웹페이지 즐겨찾기