방법: 만들고 CComPtr 및 CComQIPtr 인스턴스 사용
클래식 Windows 프로그래밍의 라이브러리 COM 개체로 (또는 COM 서버로 더 정확 하 게) 종종 구현 됩니다.여러 Windows 운영 체제 구성 요소가 COM 서버로 구현 되 고 참가자 수가에이 양식 라이브러리를 제공 합니다.COM의 기본 사항에 대 한 내용은 Component Object Model (COM).
구성 요소 개체 모델 (COM) 개체를 인스턴스화할 때 인터페이스 포인터 참조를 호출을 사용 하 여 계산을 수행 하는 COM 스마트 포인터를 저장 AddRef 및 Release 소멸자에서.ATL (액티브 템플릿 라이브러리) 또는 Microsoft Foundation 클래스 라이브러리 (MFC)를 사용 하는 경우 다음 사용 하는 CComPtr 스마트 포인터입니다.ATL 또는 MFC를 사용 하지 않는 경우 사용 _com_ptr_t.이므로 동일한 COM std::unique_ptr, 단일 소유자와 소유자 여러 시나리오에 대 한 이러한 스마트 포인터를 사용 합니다.둘 다 CComPtr 및 ComQIPtr 지원 rvalue를 참조 하는 작업을 이동 합니다.
예제
다음 예제에서는 사용 하는 방법을 보여 줍니다. CComPtr COM 개체를 인스턴스화하고 해당 인터페이스에 대 한 포인터를 얻을 수 있습니다.알은 CComPtr::CoCreateInstance 멤버 함수 같은 이름을 가진 Win32 함수 대신 COM 개체를 생성 하는 데 사용 됩니다.
void CComPtrDemo()
{
HRESULT hr = CoInitialize(NULL);
// Declare the smart pointer.
CComPtr<IGraphBuilder> pGraph;
// Use its member function CoCreateInstance to
// create the COM object and obtain the IGraphBuilder pointer.
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if(FAILED(hr)){ /*... handle hr error*/ }
// Use the overloaded -> operator to call the interface methods.
hr = pGraph->RenderFile(L"C:\\Users\\Public\\Music\\Sample Music\\Sleep Away.mp3", NULL);
if(FAILED(hr)){ /*... handle hr error*/ }
// Declare a second smart pointer and use it to
// obtain another interface from the object.
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(FAILED(hr)){ /*... handle hr error*/ }
// Obtain a third interface.
CComPtr<IMediaEvent> pEvent;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pEvent));
if(FAILED(hr)){ /*... handle hr error*/ }
// Use the second interface.
hr = pControl->Run();
if(FAILED(hr)){ /*... handle hr error*/ }
// Use the third interface.
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
CoUninitialize();
// Let the smart pointers do all reference counting.
}
CComPtr및 그 친척은 ATL의 일부인 및 atlcomcli.h에서 정의 됩니다._com_ptr_tcomip.h에 선언 되어 있습니다.컴파일러의 특수화를 만듭니다 _com_ptr_t 형식 라이브러리에 대 한 래퍼 클래스를 생성 하면 됩니다.
또한 ATL 제공 CComQIPtr, 추가 인터페이스를 검색 하는 COM 개체를 쿼리 하는 간단한 구문을 있습니다.그러나 좋습니다 CComPtr 모든 방식 때문에 CComQIPtr 수 있고 원시 COM 인터페이스 포인터를 일관 된 의미가입니다.사용 하는 경우는 CComPtr out 매개 변수를 인터페이스에 대 한 쿼리를 새 인터페이스 포인터가 놓입니다.호출이 실패 하면 HRESULT 반환 되는 일반적인 COM 패턴입니다.함께 CComQIPtr, 반환 값에 포인터 이며 호출이 실패 하면 내부 HRESULT 반환 값에 액세스할 수 없습니다.다음 두 줄 표시 방법 오류 처리 메커니즘에서 CComPtr 및 CComQIPtr 다.
// CComPtr with error handling:
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(FAILED(hr)){ /*... handle hr error*/ }
// CComQIPtr with error handling
CComQIPtr<IMediaEvent> pEvent = pControl;
if(!pEvent){ /*... handle NULL pointer error*/ }
// Use the second interface.
hr = pControl->Run();
if(FAILED(hr)){ /*... handle hr error*/ }
CComPtrCOM 자동화 구성 요소에 대 한 포인터를 저장 하 고 런타임에 바인딩을 사용 하 여 인터페이스 메서드를 호출할 수 있도록 Idispatch를 특수화를 제공 합니다.CComDispatchDriver형식에 대해 정의 된 **CComQIPtr<IDispatch, &IIDIDispatch>**에서 암시적으로 변환 될 수 있습니다 CComPtr<IDispatch>.이러한 세 개의 이름이 코드에 나타나면 따라서 것 같습니다 CComPtr<IDispatch>.다음 예제를 사용 하 여 Microsoft Word 개체 모델에 대 한 포인터를 가져오는 방법을 보여 줍니다. 한 CComPtr<IDispatch>.
void COMAutomationSmartPointerDemo()
{
CComPtr<IDispatch> pWord;
CComQIPtr<IDispatch, &IID_IDispatch> pqi = pWord;
CComDispatchDriver pDriver = pqi;
HRESULT hr;
_variant_t pOutVal;
CoInitialize(NULL);
hr = pWord.CoCreateInstance(L"Word.Application", NULL, CLSCTX_LOCAL_SERVER);
if(FAILED(hr)){ /*... handle hr error*/ }
// Make Word visible.
hr = pWord.PutPropertyByName(_bstr_t("Visible"), &_variant_t(1));
if(FAILED(hr)){ /*... handle hr error*/ }
// Get the Documents collection and store it in new CComPtr
hr = pWord.GetPropertyByName(_bstr_t("Documents"), &pOutVal);
if(FAILED(hr)){ /*... handle hr error*/ }
CComPtr<IDispatch> pDocuments = pOutVal.pdispVal;
// Use Documents to open a document
hr = pDocuments.Invoke1 (_bstr_t("Open"), &_variant_t("c:\\users\\public\\documents\\sometext.txt"),&pOutVal);
if(FAILED(hr)){ /*... handle hr error*/ }
CoUninitialize();
}