chapter 3 the component object model and directx © 2008 cengage learning emea

32
CHAPTER 3 CHAPTER 3 The Component Object Model The Component Object Model and DirectX and DirectX © 2008 Cengage Learning EM

Upload: colin-stanley

Post on 26-Dec-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

CHAPTER 3CHAPTER 3

The Component Object ModelThe Component Object Model

and DirectXand DirectX

© 2008 Cengage Learning EMEA

Page 2: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

LEARNING OBJECTIVESLEARNING OBJECTIVES

In this chapter you will learn about:– The Component Object Model– COM objects and interfaces– GUIDs and IIDs– Writing a comprehensive COM program– DirectX and the Component Object

Model– DirectX’s HRESULT value– DirectX interface creation and queries

Page 3: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

THE COMPONENT OBJECT THE COMPONENT OBJECT MODELMODEL

The Component Object Model (COM) is an object-oriented programming model used for inter-object process interaction.

Looking at COM from a higher level reveals it as a software paradigm revolving around the idea that different software components should be pluggable and interchangeable.

Page 4: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

THE COMPONENT OBJECT THE COMPONENT OBJECT MODELMODEL

COM is thus based on the idea of software componentry, that is, the idea that software components should be defined in an interchangeable manner.

COM was developed so that objects could be created in a language neutral fashion.

Language neutral objects have the benefit that they can be deployed in a vast array of environments.

Page 5: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

THE COMPONENT OBJECT THE COMPONENT OBJECT MODELMODEL

COM also permits the reuse of objects without any concern for the specific implementation of these objects.

Components thus require properly defined, stand-alone interfaces that can be accessed independently from their implementations.

COM objects are language neutral due to the objects themselves being in charge of their own creation and destruction.

Page 6: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

THE COMPONENT OBJECT THE COMPONENT OBJECT MODELMODEL

COM features a function, QueryInterface, which is responsible for casting between the different interfaces of an object – thus giving the client access to specified interfaces.

This function is part of the basic interface all other interfaces are derived from – IUnknown.

Page 7: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

THE COMPONENT OBJECT THE COMPONENT OBJECT MODELMODEL

Another interesting feature of COM objects is that new features can be added to a COM object without the functionality of the old object being impaired in the process.

Furthermore, COM objects can be replaced without the need to recompile the application program.

Page 8: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

THE COMPONENT OBJECT THE COMPONENT OBJECT MODELMODEL

COM was, before the advent of .NET, a major Microsoft software development platform and as a consequence a number of technologies were built on it.

One such technology is the DirectX Application Programming Interface.

All the DirectX components are built on top of the Component Object Model.

Page 9: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

The COM Object and The COM Object and InterfacesInterfaces

A COM object can be described as either one or more C++ classes implementing a series of interfaces.

Each interface is basically a collection of functions, and interfaces are used to communicate with COM objects.

COM-utilizing components can be accessed via the functions contained in these interfaces – thus facilitating inter-process communication.

Page 10: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA
Page 11: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

The COM Object and The COM Object and InterfacesInterfaces

COM object can contain any number of interfaces, with each interface defining a number of functions.

COM components are required to implement the standard IUnknown interface (every COM interface is thus derived from IUnknown).

The IUnknown interface can thus be described as the foundation of any interface being created.

Page 12: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

The COM Object and The COM Object and InterfacesInterfaces

The IUnknown interface defines three functions: – QueryInterface– Release – AddRef.

Page 13: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

The COM Object and The COM Object and InterfacesInterfaces

COM interfaces are reflective, transitive and symmetric.

Page 14: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

GUIDs and IIDsGUIDs and IIDs Each COM component can be

accessed using one or more interfaces.

Each interface associated with a component is uniquely identified via interface IDs (IIDs).

These identifiers, called Globally Unique Identifiers (GUIDs), are unique 128-bit values used by the QueryInterface function to access the interface of a COM object.

Page 15: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

GUIDs and IIDsGUIDs and IIDs

Page 16: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

Defining a COM ObjectDefining a COM Object

The COM object depicted in Figure 3-1 and 3-2 has four interfaces: IRenderer, I3DSound, IInput, and INetworking.

We can implement these interfaces in the following manner (notice how each interface is derived from the IUnknown class):

Page 17: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

Defining a COM ObjectDefining a COM Object/* the renderer interface *//* the renderer interface */struct IRenderer : IUnknownstruct IRenderer : IUnknown{{

virtual void InitGraphicsSystem(int renderer) = 0;virtual void InitGraphicsSystem(int renderer) = 0;virtual inter SetDisplaySize(int x, int y) = 0;virtual inter SetDisplaySize(int x, int y) = 0;......

}}

/* the 3D audio interface *//* the 3D audio interface */struct I3DSound : IUnknownstruct I3DSound : IUnknown{{

virtual void InitSoundSystem(int device) = 0;virtual void InitSoundSystem(int device) = 0;virtual bool PlayAudio(int x, int y) = 0;virtual bool PlayAudio(int x, int y) = 0;......

}}

Page 18: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

Defining a COM ObjectDefining a COM Object/* the input interface *//* the input interface */struct IInput : IUnknownstruct IInput : IUnknown{{

virtual void InitInputSystem(int controller) = 0;virtual void InitInputSystem(int controller) = 0;virtual bool HandleStickInput(float x, float y, float z)= 0;virtual bool HandleStickInput(float x, float y, float z)= 0;......

}}

/* the network interface *//* the network interface */struct INetworking : IUnknownstruct INetworking : IUnknown{{

virtual void InitNetworkingSystem(int nic) = 0;virtual void InitNetworkingSystem(int nic) = 0;virtual bool Ping(int ip)= 0;virtual bool Ping(int ip)= 0;......

}}

Page 19: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

Defining a COM ObjectDefining a COM Object

The COM class provides an implementation for each of the IUnknown interface functions as well as the above declared COM interfaces:

class GameEngine: public IRenderer,I3DSound,IInput,INetworking{private:

/* declare all the private types */

Page 20: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

Defining a COM ObjectDefining a COM Objectpublic:public:

/* implement IUnknown's QueryInterface function *//* implement IUnknown's QueryInterface function */virtual HRESULT __stdcall QueryInterface(const virtual HRESULT __stdcall QueryInterface(const

IID& iid,IID& iid,(void **) storage)(void **) storage){{

/* the actual implementation – must be /* the actual implementation – must be reflective, transitive reflective, transitive and symmetric */and symmetric */}}

/* implement IUnknown's Addref function *//* implement IUnknown's Addref function */virtual ULONG __stdcall Addref()virtual ULONG __stdcall Addref(){{

/* the actual implementation – increase the interface/* the actual implementation – increase the interface reference count for each call */reference count for each call */

}}

//etc… [see textbook for the complete listing]//etc… [see textbook for the complete listing]

Page 21: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

#include <iostream>#include <iostream>#include <malloc.h>#include <malloc.h>#include <objbase.h> //provides the set of constants used in COM #include <objbase.h> //provides the set of constants used in COM

applicationsapplications

using namespace std;using namespace std;

/* GUIDs *//* GUIDs */

// {C2F7148C-6EA5-41b4-9FB6-B4BBA4C0488F}// {C2F7148C-6EA5-41b4-9FB6-B4BBA4C0488F}const GUID GUID_IFunctionOne =const GUID GUID_IFunctionOne ={ 0xc2f7148c, 0x6ea5, 0x41b4,{ 0xc2f7148c, 0x6ea5, 0x41b4,{ 0x9f, 0xb6, 0xb4, 0xbb, 0xa4, 0xc0, 0x48, 0x8f } };{ 0x9f, 0xb6, 0xb4, 0xbb, 0xa4, 0xc0, 0x48, 0x8f } };

// {D7974908-331E-4f7c-BAB8-6711A9D1C0CC}// {D7974908-331E-4f7c-BAB8-6711A9D1C0CC}const GUID GUID_IFunctionTwo =const GUID GUID_IFunctionTwo ={ 0xd7974908, 0x331e, 0x4f7c,{ 0xd7974908, 0x331e, 0x4f7c,{ 0xba, 0xb8, 0x67, 0x11, 0xa9, 0xd1, 0xc0, 0xcc } };{ 0xba, 0xb8, 0x67, 0x11, 0xa9, 0xd1, 0xc0, 0xcc } };

Page 22: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

// {83926E15-FDF5-4fd0-B26D-A9F6E428B7A8}// {83926E15-FDF5-4fd0-B26D-A9F6E428B7A8}const GUID GUID_IFunctionThree =const GUID GUID_IFunctionThree ={ 0x83926e15, 0xfdf5, 0x4fd0,{ 0x83926e15, 0xfdf5, 0x4fd0,{ 0xb2, 0x6d, 0xa9, 0xf6, 0xe4, 0x28, 0xb7, 0xa8 } };{ 0xb2, 0x6d, 0xa9, 0xf6, 0xe4, 0x28, 0xb7, 0xa8 } };

/* the IFunctionOne interface *//* the IFunctionOne interface */interface IFunctionOne: IUnknowninterface IFunctionOne: IUnknown{{

virtual void __stdcall functionOne(void) = 0;virtual void __stdcall functionOne(void) = 0;};};

/* the IFunctionTwo interface *//* the IFunctionTwo interface */interface IFunctionTwo: IUnknowninterface IFunctionTwo: IUnknown{{

virtual void __stdcall functionTwo(void) = 0;virtual void __stdcall functionTwo(void) = 0;};};

/* the IFunctionThree interface *//* the IFunctionThree interface */interface IFunctionThree: IUnknowninterface IFunctionThree: IUnknown{{

virtual void __stdcall functionThree(void) = 0;virtual void __stdcall functionThree(void) = 0;};};

Page 23: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

class COMObject: public IFunctionOne, IFunctionTwo, IFunctionThreeclass COMObject: public IFunctionOne, IFunctionTwo, IFunctionThree{{public:public:

/* the COM object constructor *//* the COM object constructor */COMObject() : reference_counter(0) {}COMObject() : reference_counter(0) {}

/* the COM object destructor *//* the COM object destructor */~COMObject() {}~COMObject() {}

private:private:

/* declare IUnknown’s functions *//* declare IUnknown’s functions */virtual HRESULT __stdcall QueryInterface(const GUID &guid, void **storage);virtual HRESULT __stdcall QueryInterface(const GUID &guid, void **storage);

virtualvirtual void __stdcall functionOne(void);void __stdcall functionOne(void);virtual void __stdcall functionTwo(void);virtual void __stdcall functionTwo(void);virtual void __stdcall functionThree(void);virtual void __stdcall functionThree(void);

virtual ULONG __stdcall AddRef();virtual ULONG __stdcall AddRef();virtual ULONG __stdcall Release();virtual ULONG __stdcall Release();

/* the reference counter *//* the reference counter */int reference_counter;int reference_counter;

};};

Page 24: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

void COMObject::functionOne(void){}void COMObject::functionOne(void){}void COMObject::functionTwo(void){}void COMObject::functionTwo(void){}void COMObject::functionThree(void){}void COMObject::functionThree(void){}

HRESULT __stdcall COMObject::QueryInterface(const GUID &guid, void **storage)HRESULT __stdcall COMObject::QueryInterface(const GUID &guid, void **storage){{

/* start by calling the IUnknown base interface with/* start by calling the IUnknown base interface with IDD_IUnknown, the ID of the IUnknown interface */IDD_IUnknown, the ID of the IUnknown interface */if(guid == IID_IUnknown)if(guid == IID_IUnknown){{

/* cast the 'this' pointer to the IUnknown interface/* cast the 'this' pointer to the IUnknown interfacerequested */requested */*storage = (IFunctionOne*)this;*storage = (IFunctionOne*)this;

}}

/* the IFunctionOne interface has been requested *//* the IFunctionOne interface has been requested */if(guid == GUID_IFunctionOne)if(guid == GUID_IFunctionOne){{

/* cast the 'this' pointer to the IFunctionOne/* cast the 'this' pointer to the IFunctionOne interface requested */interface requested */*storage = (IFunctionOne*)this;*storage = (IFunctionOne*)this;

}}

Page 25: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

/* the IFunctionTwo interface has been requested *//* the IFunctionTwo interface has been requested */else if(guid == GUID_IFunctionTwo)else if(guid == GUID_IFunctionTwo){{

/* cast the 'this' pointer to the IFunctionTwo/* cast the 'this' pointer to the IFunctionTwo interface requested */interface requested */*storage = (IFunctionTwo*)this;*storage = (IFunctionTwo*)this;

}}

/* the IFunctionThree interface has been requested *//* the IFunctionThree interface has been requested */else if(guid == GUID_IFunctionThree)else if(guid == GUID_IFunctionThree){{/* cast the 'this' pointer to the IFunctionThree/* cast the 'this' pointer to the IFunctionThree interface requested */interface requested */*storage = (IFunctionThree*)this;*storage = (IFunctionThree*)this;}}

/* the requested interface could not be found *//* the requested interface could not be found */elseelse{{

*storage = NULL;*storage = NULL;/* QueryInterface should return the error/* QueryInterface should return the error E_NOINTERFACE if it fails */E_NOINTERFACE if it fails */return(E_NOINTERFACE);return(E_NOINTERFACE);

}}

Page 26: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

/* cast the pointer to IUnknown, subsequently calling the/* cast the pointer to IUnknown, subsequently calling the AddRef function so that the reference count can beAddRef function so that the reference count can be incremented */incremented */((IUnknown *)(*storage))->AddRef();((IUnknown *)(*storage))->AddRef();

/* QueryInterface should return NOERROR if it succeeds *//* QueryInterface should return NOERROR if it succeeds */return(NOERROR);return(NOERROR);

}}

ULONG __stdcall COMObject::AddRef()ULONG __stdcall COMObject::AddRef(){{

/* increment the reference count *//* increment the reference count */reference_counter = reference_counter + 1;reference_counter = reference_counter + 1;

/* return this counter for debugging purposes *//* return this counter for debugging purposes */return(reference_counter);return(reference_counter);

}}

Page 27: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

ULONG __stdcall COMObject::Release()ULONG __stdcall COMObject::Release(){{

/* decrement the reference count *//* decrement the reference count */reference_counter = reference_counter - 1;reference_counter = reference_counter - 1;

/* check whether the counter isn't ‘0’ *//* check whether the counter isn't ‘0’ */if(reference_counter == 0)if(reference_counter == 0){{

/* the interface pointer is now invalid, so destroy it *//* the interface pointer is now invalid, so destroy it */delete this;delete this;return 0;return 0;

}}elseelse

/* return this counter for debugging purposes *//* return this counter for debugging purposes */return(reference_counter);return(reference_counter);

}}

Page 28: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

IUnknown *CoCreateInstance()IUnknown *CoCreateInstance(){{

/* create the COM object using a pointer to any of our/* create the COM object using a pointer to any of our interfaces – used IFunctionOne in this case*/interfaces – used IFunctionOne in this case*/IUnknown *comObj = (IFunctionOne *)new(COMObject);IUnknown *comObj = (IFunctionOne *)new(COMObject);

/* increment the reference count *//* increment the reference count */comObj->AddRef();comObj->AddRef();

/* return the create COM object *//* return the create COM object */return(comObj);return(comObj);

}}

Page 29: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

A Comprehensive COM A Comprehensive COM ProgramProgram

int main()int main(){{

/* the main COM object *//* the main COM object */IUnknown *mainCOMObject = CoCreateInstance();IUnknown *mainCOMObject = CoCreateInstance();

IFunctionOne *pInterfaceOne = NULL;IFunctionOne *pInterfaceOne = NULL;IFunctionTwo *pInterfaceTwo = NULL;IFunctionTwo *pInterfaceTwo = NULL;IFunctionThree *pInterfaceThree = NULL;IFunctionThree *pInterfaceThree = NULL;

/* query all three interfaces *//* query all three interfaces */mainCOMObject->QueryInterface(GUID_IFunctionOne, (void **)&pInterfaceOne);mainCOMObject->QueryInterface(GUID_IFunctionOne, (void **)&pInterfaceOne);mainCOMObject->QueryInterface(GUID_IFunctionTwo, (void **)&pInterfaceOne);mainCOMObject->QueryInterface(GUID_IFunctionTwo, (void **)&pInterfaceOne);mainCOMObject->QueryInterface(GUID_IFunctionThree, (void mainCOMObject->QueryInterface(GUID_IFunctionThree, (void **)&pInterfaceThree);**)&pInterfaceThree);

/* release the interfaces *//* release the interfaces */pInterfaceOne->Release();pInterfaceOne->Release();

/* release the main COM object *//* release the main COM object */mainCOMObject->Release();mainCOMObject->Release();

return 0;return 0;}}

Page 30: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

DIRECTX AND THE DIRECTX AND THE COMPONENT OBJECT MODELCOMPONENT OBJECT MODEL

DirectX is, at its most basic level, comprised of a number of COM objects.

A DirectX function call indirectly creates a COM object, returning the interface of the object.– This is done by passing the address of

an interface pointer to the DirectX function.

Page 31: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

DIRECTX AND THE DIRECTX AND THE COMPONENT OBJECT MODELCOMPONENT OBJECT MODEL

When creating an interface (ID3D10Device and ID3D10DepthStencilView in this case), we start by declaring a pointer to the interface (notice the last parameter receiving the address of the ID3D10DepthStencilView interface pointer):

ID3D10Device* pID3D10Device;ID3D10DepthStencilView* pDepthStencilView;

pID3D10Device->CreateDepthStencilView(pDepthStencilBuffer&depthstencilviewDescription,&pDepthStencilView);

Page 32: CHAPTER 3 The Component Object Model and DirectX © 2008 Cengage Learning EMEA

DIRECTX AND THE DIRECTX AND THE COMPONENT OBJECT MODEL COMPONENT OBJECT MODEL

ValuesValues DirectX’s HRESULT Values DirectX Interface Creation and

Queries