COM 스터디 요약 정리

프로그래밍 2018. 5. 16. 13:25 Posted by 정직한 UnHa Kim

리뷰했던 DCOM 관련 서적을 읽은 내용 요약.


COM interface : contract regarding a provided service

IID : interface identifier. a 128-bit globally unique identifier(GUID).

IUnknown : All COM interface must be derived from. (necessary)
IUnknown.QueryInterface : the method used for 'dynamic discovery' of another interface from the object.
IUnknown.AddRef : Object reference count is incremented for management of an object's life cycle.
IUnknown.Release : Object reference count is decremented for management of an object's life cycle.

vtbl : table of function pointers. only a single vtbl exists per class. (not instance)
vptr : pointer to a vtbl (in each instance)

type library : the storage where all the type information of an object is stored
tlb : conventional separated type library file. embedded & integrated in DLL, OCX file.

IDispatch : support dynamic invocation. (optional)
dispatch interface. contains 'a dispatch identifier' (dispid) that aliases an actual method.
'dispid' also can be dynamically discovered through lookup operation.

IConnectionPoint : supports event notification. (optional)

Event : COM supports events via a concept called 'connection points' between 'source' and 'sink'(client).

Basics of COM
1. COM interface : a number of related methods
2. COM object : implements a number of interfaces, must implement 'IUnknown'
3. COM class factory : special COM object that creates or instantiates other COM objects

CLSID : class ID. Like interfaces, libraries, a COM class have unique UUID, specifically called CLSID.

HRESULT : Every COM interface method returns an HRESULT.  (32bit value composed of 4 different parts.)

1. Severity : Was the call successful? 1bit answer. 0 : success, 1 : failure
2. Reserved : 2bits that must be always 0. (Don't mess with it)
3. Facility : Who generated the error? 13bits facility code (indicating RPC, Win32, DISPATCH, etc...)
4. Code : What actually happened? 16bits return code specific to a facility

FACILITY_NULL includes a number of generic and convenient status codes.
Some of these status codes include:
- S_OK : Success
- S_FALSE : False
- E_UNEXPECTED : Unexpected, can be a catastrophic failure
- E_NOTIMPL : Method not implemented
- E_OUTOFMEMORY : Errors dealing with memory allocations
- E_NOINTERFACE : Interface not supported, used in QueryInterface
- E_POINTER : Invalid pointer
- E_FAIL : Generic error, no details available

COM supports a finite list of data types for arguments.
Base Data Types : boolean, byte, char, wchar_t, float, double, small, short, long, hyper, IUnknown*

Extended Data Types (dynamic invocation(=Automation) compatible)
- VARIANTS : a universal data type. technically a union of a bunch of special data types.

3 names for an interface
- GUID (IID_Ixxx) : uniquely identifies an interface
- class or structure name (Ixxx)
- human readable name (xxx.1)

IDispatch supports dynamic invocation but may suffer performance problem from extensive lookup.
For performance, there are other type of invocation the 'dual interface'.

Very Early Binding (vtbl binding)
Client need to be compiled with a given header file generated by MIDL.
Calls are made directly via pointers and gives maximum performance.

Early Binding (static invocation through IDispatch)
Require prior knowledge of 'dispid's.
Development tools can obtain these 'dispid's from a type library.
Since the 'dispid's are already resolved, clients don't have to call GetIDsOfNames,
which means you no longer have the performance hit of looking up 'dispid's.

Bidirectional communication.
- Client can talk to a server by calling an interface
- Server can "call back" to the client to notify them of "events" that are of interest. (Event Source)
- Implement COM object on the client side that exposes a callback interface for the server's use. (Event Sink)

Standard interfaces to support bidirectional communication through call back.
- IConnectionPointContainer
- IConnectionPoint

HRESULT IConnectionPointContainer.EnumConnectionPoints([out] IEnumConnectionPoints **ppEnum)
HRESULT FindConnectionPoint([in] REFIID riid, [out] IConnectionPoint **ppCP)

- Knows about all connection points(IConnectionPoint) that the "event source" supports.
- Client can use the IConnectionPointContainer interface to ask the object whether it supports a particular connection point.
- Client also can use this interface to enumerate (via IEnumConnectionPoints) all the connection points supported by the source object.

HRESULT GetConnectionInterface([out] IID *piid)
HRESULT GetConnectionPointContainer([out] IConnectionPointContainer **ppCPC)
HRESULT Advise([in] IUnknown *pUnkownSink, [out] DWORD *pdwCookie)
HRESULT Unadvise([in] DWORD dwCookie)
HRESULT EnumConnections([out] IEnumConnections **ppEnum)

- This interface allows a sink to call Advise to signal that it is interested in receiving callbacks.
- The connection point object is not the same object as the server COM object that implements the IConnectPointContainer interface.

Given these two standard interfaces, an event source is responsible for following:
1. Implementing the standard IConnectionPointContainer interface.
   This interface allows the sinks to enumerate or find connection points supported by the event source.
2. Implementing the standard IConnectionPoint interface for each outgoing interface.
   This is done to allow the event sink to establish a connection with the source.
   During connection, the sink sends a callback interface pointer to the source,
   so that the source can later make callbacks.
3. Calling back to the registered event sink.

An event sink is responsible for following:
1. Implementing the event sink object so that the event source can make callbacks.
2. Notifying the event source that it is interested in receiving events.
   A sink typically requests the IConnectionPointContainer interface from the event source
    and calls FindConnectionPoint to make sure that the
    event source supports the callback interface implemented by the event sink.
   This will return an IConnectionPoint interface pointer associated with the callback interface.
   A sink then uses the returned IConnectionPoint interface pointer to call Advise.
   In this method invocation, the sink sends a pointer to the its own callback interface to the event source.
   When this invocation returns, the sink will receive a registration cookie.
3. When a sink object no longer wants to receive events associated with the callback interface,
    it must notify the event source of this withdrawl by calling Unadvise using the registration cookie,
    received from calling Advise.

An event source can be thought of as a container that holds a bunch of connection point

댓글을 달아 주세요