This forum has been archived. Please start a new discussion on GitHub.

Implementing ICE interface for existing class library

I'm currently investigating how I best implement an ICE interface for an existing class library.

In an ideal world the entire public interface of all classes would be accessible through ICE and the oo features (polymorphism, inheritance, etc.) in the library would also exist in the ICE interface.

Here is a simple example:
class WorldCitizen
    virtual std::string SayHello() = 0;

class French : public WorldCitizen
    virtual std::string SayHello() { return "Bonjour"; }

Numerous little problems creep in if I simply create matching interface definitions and inherit from the slice generated proxies for the interfaces.

I wonder what the best approach is to accomplish this and would greatly appreciate some clues.


  • benoit
    benoit Rennes, France

    Creating matching interfaces is probably the most straightforward solution if you want to expose all the library functionality through an Ice server but this might be quite some work! Another option is to declare simpler interfaces to only expose a subset of the library features (the facade design pattern).

    Perhaps you could detail a little more the problems you ran into? Why are you trying to inherit from the proxy generated classes for instance?

  • Well I was wrong with my statement that I "... inherit from the slice generated proxy classes". I got a bit lost in the forest of classes and namespaces that slice created for me.

    At this stage, the main problem I'm having is the object life cycle. If a class inherits directly or indirectly from ::Ice::Object I find that Ice calls the destructor of my class which in my case is an undesirable side effect. In my case this is critical because an object with an Ice interface is created during static initialisation.
  • Ice does not call any destructor explicitly. This simply happens as a side effect when your servant gets destroyed.

    Note that all servants must inherit from Ice::Object, and therefore all of them must be allocated with new because of reference counting. You cannot allocate a servant on the stack. Please see the Ice manual for details, in particular the section about reference counting.
  • marc wrote:
    Ice does not call any destructor explicitly. This simply happens as a side effect when your servant gets destroyed.

    Just to explain what I'm doing let's call my application class testApp (which is based on Ice::Application). Let's also assume that I have a simple slice interface called Person and the class that implements this interface is IPerson.

    So what I do is create an ObjectAdapter in my testApp::Run method, create an instance of my IPerson class and register it with the object adapter. The run method then waits with communicator()->waitForShutdown(). Ultimately, this call returns and in due course the testApp instance gets destroyed. It is at this point that the IPerson instance is also deleted by code inside ICE.

    How can I ensure that the object continues to live beyond this point?

    BTW: I also tried to call ObjectAdapter::remove to remove the IPerson instance from the object adapter but this too resulted in the destruction of my IPerson instance.
  • You must keep a smart pointer to the servant to avoid that it gets destroyed prematurely. For details, please see the chapter about C++ reference counting (6.14.6) in the Ice manual.