The TQualityOfService object that is passed into the constructor of the TStandardServiceDefinition object determines whether or not the service is accessible to programs on remote machines. This example only allows for local access, not remote.
Users of TServiceDefinition must take care to properly increment the reference count after creating it. TServiceDefinition will delete itself when the reference count goes to zero, so you should not delete it yourself.
TDispatcherThread is used to launch the dispatcher. This starts another thread which does the dispatching. For another way to start a dispatcher, look at the TemplateRPC sample.
It creates a caller and makes remote calls with it.
The try-catch block demonstrates that if an exception is thrown in the dispatcher, it is propagated through the caller.
MRemoteCaller objects have an ExitDispatcher call that shuts down the dispatcher.
It isn't necessary to start the dispatcher if it isn't running because making a remote call cause it to autostart.
The MRemoteCallerDeclarationsMacro is necessary for RPC to work.
TAdditionCaller stores the transport because it creates the transport, and its superclass MRemoteCaller uses the transport but doesn't adopt it, because the transport could be used by another object.
It is essential that MRemoteCallerEnable is called at the beginning of every constructor.
The only domain-specific member functions are Add and AddOne.
The copy constructor and assignment operator are private. Their implementations are exposed to demonstrate that you never copy a dispatcher.
The streaming operators are private. Their implementations are exposed to demonstrate that you can't stream a dispatcher.
The only domain-specific member functions are AddStub and AddOneStub.
Note that the stub functions simply call out to the implementation. The dispatcher just dispatches, it doesn't contain any logic. Also note that the TAdditionImplementation object can throw math exceptions, but the dispatcher doesn't do anything because MRemoteDispatcher takes care of any exceptions and propagates them through to the caller.
RPC is used instead of message streams because: RPC takes care of marshalling and unmarshalling parameters; it propagates exceptions from the dispatcher to the caller; and it is more invisible--if done properly RPC can look like regular function calls, rather than obvious remote communication (like message streams).