Windows NT Systems Programming

[ Home | Syllabus |Course Notes]


Distributed Objects


Different Models of Distribution


Issues


CORBA

Common Object Request Broker Architecture (specification)

 


Java Distributed Objects


COM   


Historical Perspective


OLE 1.0


OLE 2.0


OLE Controls (OCXs)


32 bit OLE/COM/ActiveX


COM basics

 


IUnknown

HRESULT QueryInterface(REFIID iid, void** ppvObject);
ULONG AddRef(void);
ULONG Release(void);

Identifiers


Using COM


COM Servers

dcom.gif (32122 bytes)


An Example

 

// 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;
};

rainbow.gif (2243 bytes)


Implementation of Objects

 

// 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;
}

Interface Definition File

 

// 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;
	};

};

Client Side:

// 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;
}

rainbow.gif (2243 bytes)


Copyright chris wild 1997.
For problems or questions regarding this web contact [Dr. Wild].
Last updated: November 23, 1997.