[ Home | Syllabus |Course Notes]
Common Object Request Broker Architecture (specification)
HRESULT QueryInterface(REFIID iid, void** ppvObject); ULONG AddRef(void); ULONG Release(void);
// LabObj.h : Declaration of the CLabrador // // This is a part of the ActiveX Template Library. // Copyright (C) 1996 Microsoft Corporation // All rights reserved. #include "labres.h" // main symbols class CLabrador : public IMammal, public IDog, public CComObjectRoot, public CComCoClass<CLabrador, &CLSID_Labrador> // Template { public: CLabrador(); BEGIN_COM_MAP(CLabrador) COM_INTERFACE_ENTRY(IMammal) COM_INTERFACE_ENTRY(IDog) END_COM_MAP() DECLARE_NOT_AGGREGATABLE(CLabrador) DECLARE_REGISTRY(CLabrador, _T("LABRADOR.Labrador.1"), _T("LABRADOR.Labrador.1"), IDS_LABRADOR_DESC, THREADFLAGS_BOTH) // IDog STDMETHOD(GetPetName)(MY_BSTR pStr); STDMETHOD(SetPetName)(MY_BSTR pStr); STDMETHOD(IsBarking)(BOOL* pBool); // IMammal STDMETHOD(GetSpeciesName)(MY_BSTR pStr); STDMETHOD(IsAlive)(BOOL* pBool); private: WCHAR m_szPetName[32]; WCHAR m_szSpeciesName[32]; BOOL m_bIsBarking; BOOL m_bIsAlive; };
// LabObj.cpp : Implementation of CLabradorApp and DLL registration. #include "prelab.h" #include "Labrador.h" #include "LabObj.h" #include <wchar.h> ///////////////////////////////////////////////////////////////////////////// // CLabrador Interface Implementation CLabrador::CLabrador() { wcscpy(m_szPetName, L"Fido"); wcscpy(m_szSpeciesName, L"Warthog"); m_bIsAlive = TRUE; m_bIsBarking = FALSE; } ///////////////////////////////////////////////////////////////////////////// // IDog Implementation STDMETHODIMP CLabrador::GetPetName(MY_BSTR pStr) { if (pStr) wcscpy(pStr, m_szPetName); return (HRESULT)NOERROR; } STDMETHODIMP CLabrador::SetPetName(MY_BSTR pStr) { if (pStr) { wcscpy(m_szPetName, pStr); return S_OK; } return E_POINTER; } STDMETHODIMP CLabrador::IsBarking(BOOL* pBool) { if (pBool) { *pBool = m_bIsBarking; return S_OK; } return E_POINTER; } ///////////////////////////////////////////////////////////////////////////// // IMammal Implementation STDMETHODIMP CLabrador::GetSpeciesName(MY_BSTR pStr) { if (pStr != NULL) wcscpy(pStr, m_szSpeciesName); return (HRESULT)NOERROR; } STDMETHODIMP CLabrador::IsAlive(BOOL* pBool) { if (pBool) { *pBool = m_bIsAlive; return S_OK; } return E_POINTER; }
// Labrador.idl : IDL source for Labrador.dll // This file will be processed by the MIDL tool to // produce the type library (Labrador.tlb) and marshalling code. import "unknwn.idl"; #define MAX_MY_BSTR_LEN 32 typedef [string] WCHAR MY_BSTR[MAX_MY_BSTR_LEN]; [ object, uuid(62A33E75-932A-11CF-B056-00A0C90348FA), helpstring("IMammal Interface"), pointer_default(unique) ] interface IMammal : IUnknown { import "oaidl.idl"; HRESULT GetSpeciesName([out, string] MY_BSTR p); HRESULT IsAlive([out] BOOL* pBool); }; [ object, uuid(62A33E76-932A-11CF-B056-00A0C90348FA), helpstring("IDog Interface"), pointer_default(unique) ] interface IDog : IUnknown { import "oaidl.idl"; HRESULT GetPetName([out, string] MY_BSTR p); HRESULT SetPetName([in, string] MY_BSTR p); HRESULT IsBarking([out] BOOL* pBool); }; [ uuid(62A33E74-932A-11CF-B056-00A0C90348FA), version(1.0), helpstring("Labrador 1.0 Type Library") ] library LABRADORLib { importlib("stdole32.tlb"); [ uuid(62A33E79-932A-11CF-B056-00A0C90348FA), helpstring("Labrador Class") ] coclass Labrador { [default] interface IMammal; interface IDog; }; };
// labdriv.cpp : driver for the Labrador sample #include "prelabdr.h" /////////////////////////////////////////////////////////////// // helper to do print traces void _cdecl Trace(LPCTSTR lpszFormat, ...) { va_list args; va_start(args, lpszFormat); int nBuf; TCHAR szBuffer[512]; nBuf = _vstprintf(szBuffer, lpszFormat, args); _ASSERTE(nBuf < sizeof(szBuffer)); _tprintf(szBuffer); OutputDebugString(szBuffer); va_end(args); } // helper function to do the work void _cdecl CallLabrador() { WCHAR szTmp[32]; Trace(_T("\nSTARTING\n=============================\n")); Trace(_T("Calling CoCreateInstance()...\n")); IUnknown* pUnk = NULL; HRESULT hRes = CoCreateInstance(CLSID_Labrador, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pUnk); if (FAILED(hRes)) { Trace(_T("Failed to create Labrador\n")); return; } Trace(_T("Object created\n")); IMammal* pMammal = NULL; hRes = pUnk->QueryInterface(IID_IMammal, (LPVOID*)&pMammal); pUnk->Release(); if (FAILED(hRes)) { Trace(_T("QueryInterface() for IMammal failed\n")); return; } Trace(_T("Calling through IMammal methods...\n")); pMammal->GetSpeciesName(szTmp); Trace(_T("Species name is <%ls>\n"), szTmp); BOOL bIsAlive; pMammal->IsAlive(&bIsAlive); if (bIsAlive) Trace(_T("And it's alive!\n")); else Trace(_T("And it's dead!\n")); IDog* pDog = NULL; hRes = pMammal->QueryInterface(IID_IDog, (void**)&pDog); pMammal->Release(); if (FAILED(hRes)) { Trace(_T("QueryInterface() for IDog failed\n")); return; } Trace(_T("Calling through IDog methods...\n")); BOOL bIsBarking; pDog->GetPetName(szTmp); Trace(_T("Dog's name is <%ls>\n"), szTmp); pDog->IsBarking(&bIsBarking); if (bIsBarking) printf("BARK! BARK! BARK! BARK!\n"); pDog->SetPetName(L"KIVA"); pDog->GetPetName(szTmp); printf("Dog's New name is <%ls>\n", szTmp); Trace(_T("Releasing Object\n")); pDog->Release(); Trace(_T("\nDONE!!!\n=============================\n")); } int main( int argc, char *argv[ ]) { if (FAILED(CoInitialize(NULL))) return -1; CallLabrador(); #ifdef _DEBUG _CrtDumpMemoryLeaks(); #endif CoUninitialize(); return 0; }