COM – Component Object Model
History: Clipboard->DDE->OLE->COM/OLE2->ActiveX/DCOM->COM+
COM: Component Requirement
Interoperability: enable communication and interaction
mechanism between arbitrary applications
Scalability: no limit to the number of communications
partners.
Language Independence: supports any language, Binary
Standard: Components shipped in binary form
Location Transparency: transparently relocatable (I-process,
exe ,remote)
Versions: robustness to extensions
Com specification: provides the Standard, that components
and clients follow to ensure that they can operate together.
-An Interface is uniquely identified by an Interface Identifier
(IID)
-is derived from the standard Interface IUnkown
Enhancements 1
-Query Interface: dynamic querying of the interfaces
of an object
-Reference counting: count number of references to interface
of an object, remove object if count reaches zero
-Abstract Factory: provide an interface for creating
objects without specifying their concrete classes
interface IUnknown
{
HRESULT
_stdcall QueryInterface(const IID& iid, void**
ppv)=0;
//test if interface is supported
ULONG
_stdcall AddRef(
);
//increments reference count
ULONG
_stdcall Release(
);
//decrements reference
};
interface IClassFactory : public IUnknown
{
HRESULT CreateInstance(IUnknown pUnkOuter,
REFIID iid, void* ppvObj); //returns pointer to interface
HRESULT LockServer (Bool fLock);
}
Enhancements 2
-identify every class by a unique class identifier CLSID
- provide a function ::CoGetClassObject for creating
class factories without specifying their concrete classes
- ::CoGetClassObject return an Interface pointer to
a factory for creating instances of a class CLSId
IClassFactory* pClfSpaceship; IMotion pMot;
HRESULT
hr =
::CoGetClassObject(CLSI_Cspaceship,
//this is a shortcut to create instances
CLSCTX_INPORC_SERVER,
//run component as dll
NULL,, IID_IclassFactory,
(void**) &pClfSpaceship);
if (SUCCEEDED(hr))
{
hr=pCLSSpaceship->CreateInstance(NULL,IID_Imotion,
(void**) &pMot);
… }
-define by OSF/DCE (UUID) : 128 bits(16bytes), 48 bits machine
id and 60 bits timestamp
-IID Interface Identifier
-CLSID component Identifier
-ProgId user-friendly component name
HRESULT : 32 bit error code
bits 31-16 Facility. ex. FACILITY_RPC, bits 15-0 Return
Code ex. S_OK, S_FALSE
Testing
HRESULT
definded in WINERROR.H
if (FAILED(hr)) return;
if (SUCCEEDED (hr ) ) { …}
Short Client Example
#include “..\DLLServer\intercace.h” //import interface and iid’s
…
int main()
{
CoIninitialize(NULL);
hr = ::CoCreateInterface(…..=
if (FAILED(hr)) exit(1);
hr = pMot->QueryInterface(IID_Ithrust, (void**)
&pThr);
pThr->MethodBlabla(10);
pThr->Release( );
pMot->Release( );
CoUninitialize( );
return (0);
}
-implements classes (components) and theis class factories
-registers the classes it supports with the registry
-initializes the COM library
-exposes its class factories
-provide an unloading mechanism
-unitilializes the COM library
IN-process server (DLL) : execute in the same process as theis
clients
Server-DLL exports
-DllGetClassObject Class Exposre
-DllCanUnloadNow Unloading
-DllRegisterServer
Registering of the class id’s into registry
-DllUnregisterServer Deregistering,
remove entries from registry
DllGetClassObject(…) is called from CoGetClassObject to retrieve
the class factory
Vorteil DLL-Server:
sehr effizient, sehr schnell
Nachteil DLL-Server: Alles stürzt auf einmal ab Server+Clients
Local server (EXE):
execute in a separate process, Lightweight RPS is used as IPC mechanism
Kommunikation mit IPC: Inter Process Call
Remote Server (DCOM): execute in a separate process, DCE-like
RPC us uses as IPC-mechanism
Kommunikation mit RPC (marshalling): Remote Process Call
-Server is Loaded by COM (lifecycle)
-Client can call IclassFactory::Lock(true) to prevent
the server from unloading
Win32 SDK includes MIDL compiler MIDL.exe
MIDL Example -> ergibt Type Library .TLB-File (kann unabhängig
oder eingebunden in DLL oder EXE-File genutzt werden)
import
“unknwn.idl”;
//import declaration of IUnknown
//Interface IX
[
object,
uuid(32bb8323-b41b-11cf-a6bb-0080c7b2d682),
helpstring(“IX Interface”),
pointer_default(unique)
]
interface IX : Iunknown
{
HRESULT FxStringIn([in, string] wchar_t* szIn);
HRESULT FxStringOut([out, string] wchar_t** szOut);
};
-Defines another way for clients and components to communicate
-Dynamic (late) Binding
-easy access to COM objects
-Drawbacks (only VB Types supported, slow)
&QueryInterface, &AddRef, &Release, &GetTypeInfoCount,
&GetTypeInfo, &GetIDsOfNames, &Invoke
The VARIANT structure is a union of all Automation-compatible
types
Variant Helper Functions: VariantChangeType(Ex), VariantClear,
VariantCopy, VarianCopyInd, VariantInit
BSTR: Basic String :
a length-prefixed, null-terminated array of Unicode characters
-includes Callbacks
-Properties, propget and propput, Automation Clients
treat properties like attributes
Com’s Observer Pattern
-Based on Callbacks
-COM-Object can have one or more event sources
-Per event source may be one or more subscribed event
sink
-asynchronous communication between a server and its
clients
//Client
class myEventSink : public EventSink
{
void handleEvent(int arg)
{ cout << “myEventHandler” << arg << endl; }
};
//Server
[ object, uuid(…) }
interface IEventSource : IUnknown
{
HRESULT Attach( [in] IEventSink* PEveSink);
};
Protocol
IConnectionPointContainer::FindConnectionPoint
IConnectionPoint::Advise //passing sink interface pointer, receiving
cookie
IConnectionPoint::Unadvice //terminates notification
-Entwicklungsumgebung für COM-Komponenten
-bassiert auf Template Klassen und Macros
-kombiniert mit STL praktisch für die Entwicklung von COM-Objekten