Here is a quick sample application that demonstrates what I mean by SOAP interface delegation. Imagine you have a COM object of CoClass COMObj that exposes an interface ICOMObj (I know, real original names...but this is an example). On your (client) machine, this is a real COM object versus a registered type library only, and at times you want to use the local copy and at times you want to remote the interface's method calls using SOAP. That scenario is perfect for the delegation use model.

To use delegation, you first create an instance of the SOAP Object Surrogate and obtain a pointer to its ISoapControl interface. Then you create an instance of COMObj using ISoapControl::CreateInstance(). The pointer you obtain from ISoapControl will appear to your object's client to be a pointer to the true COM object. In reality, though, it'll be a delegated pointer that is managed by the SOAP Object Surrogate, and method calls using that pointer will be shipped to the remote server using the information recorded in the SOAP Catalog for that interface.

The code example:

#include <iostream>
#include <atlbase.h>
#include "..\SOAPObjectSurrogate\SOAPObjectSurrogateLib.h"
#include "..\COMObj\COMObj.h"

using namespace std;

int main(int argc, char* argv[])
{
    CoInitialize(NULL);

    HRESULT hr = S_OK;
    try {
        CComPtr<ISoapControl> spController;
        hr = spController.CoCreateInstance(__uuidof(SoapObjectSurrogate));
        if ( FAILED(hr) ) throw hr;
        cout << "Surrogate successfully created..." << endl;

        CComPtr<IUnknown> spUnk;
        hr = spController->CreateInstance(__uuidof(COMObj),__uuidof(ICOMObj),&spUnk);
        if ( FAILED(hr) ) throw hr;
        cout << "(Delegated) Object successfully created..." << endl;

        CComQIPtr<ICOMObj> spObject;
        spObject = spUnk;
        if ( spObject.p == NULL ) throw E_POINTER;
        cout << "Object successfully QI'd..." << endl;

        // Call a method...imagine the method signature:

        // HRESULT SomeMethod([in] long x, [in] BSTR str);
        long x = 1234;
        CComBSTR str("Hello, World!");
        hr = spObject->SomeMethod(x,str);
        if ( FAILED(hr) ) throw hr;

        // Print results
        cout << "Success!" << endl;
    } // try
    catch(HRESULT hrErr) {
        // Some COM error...
        hr = hrErr;
        char strErrMsg[256] = {0};
        wsprintf(strErrMsg,"COM error %#08x",hrErr);
        cout << strErrMsg << endl;
    } // catch
    catch(...) {
        // Some error...
        hr = E_UNEXPECTED;
        cout << "Unexpected application error" << endl;
    } // catch

    CoUninitialize();
    return hr;
}