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;
}