For an overview of the role of client objects in interacting with the debugger engine, see Client Objects.
In general, a client's methods may be called only from the thread in which the client was created. Typically, methods called from the wrong thread will fail immediately. The notable exception to this rule is the method CreateClient; this method may be called from any thread, and returns a new client that can be used in the thread from which it was called. Other exceptions are documented in the reference section.
The debugger engine API contains several COM like interfaces; they implement the IUnknown interface.
The interfaces described in the section Debug Engine Interfaces is implemented by the client (though not necessarily at the latest version). You may use the COM method IUnknown::QueryInterface to obtain each of these interfaces from any of the others.
The clients implement the IUnknown COM interface and use it for maintaining reference counts and interface selection. However, the clients are not registered COM objects. The method IUnknown::AddRef is used to increment the reference count on the object, and the method IUnknown::Release is used to decrement the reference count. When IUnknown::QueryInterface is called, the reference count is incremented, so when a client interface pointer is no longer needed IUnknown::Release should be called to decrement the reference count.
See the Platform SDK for more information about when reference counts should be incremented and decremented.
IUnknown::QueryInterface, DebugCreate, and DebugConnect each take an interface ID as one of their arguments. This interface ID can be obtained using the __uuidof operator. For example:
IDebugClient * debugClient; HRESULT Hr = DebugCreate( __uuidof(IDebugClient), (void **)&debugClient );
Important The IDebug* interfaces such as IDebugEventCallbacks interface, although COM like, are not proper COM APIs. Calling these interfaces from managed code is an unsupported scenario. Issues such as garbage collection and thread ownership, lead to system instability when the interfaces are called with managed code.