Archived

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

ICE 4 c++ beginner question

I am new to ICE and the whole OO Middleware stuff.
For the last 3 Days I read the Dokumentation and tried out the various simple examples mentioned in the Documentation. But i didn't find anything "matching" my Application i'd like to iceify. Also the examples (.../demo/ice) didn't help me so far.

I have an Application holding a couple of instances of various classes depending on each other and i just want to access this objects via ice.
Consider A to be a Singleton.

For example:
class C
	{
	private:
		int id;
	
	public:
		C();
		~C();
		
		int getID();
		
		void someCMethod();
	};

class B
	{
	private:
		C* myC;
		int id;
	
	public:
		B(C* cc);
		~B();
		
		C* getC();
		int getID();
		
		void someBMethod();
	};
		

class A
	{
	private:
		vector<B*> bs;
		vector<C*> cs;

	public:
		A();
		~A();
		
		B* findB(C* cc, int id);
		C* findC(int id);
		
		void someAMethod();
	};


So I wrote an ice interface looking something like this:
module mymodule
	{
	interface A;
	interface B;
	interface C;
	
	interface IFA
		{
		B* findB(C* cc, int id);
		C* findC(int id);
		
		void someAMethod();
		};
	
	interface IFB
		{
		C* getC();
		int getID();
		
		void someBMethod();
		};
	
	interface IFC
		{
		int getID();
		
		void someCMethod();
		};
	};

slice2cpp generates the .cpp and .h file without further comments.
So i naivly started to implement the Server:
class IFAI : public IFA
	{
	public:
		virtual IFBPrx findB(IFCPrx cc, int id);
		virtual IFCPrx findC(int id);
		
		virtual void someAMethod();
	};

class IFBI : public IFB
	{
	public:
		virtual IFCPrx getC();
		virtual int getID();
		
		virtual void someBMethod();
	};

class IFCI : public IFC
	{
	public:
		virtual int getID();
		
		virtual void someCMethod();
	};

Now to the trivial Parts:
void IFAI::someAMethod() {}
void IFBI::someBMethod() {}
void IFCI::someCMethod() {}
int IFBI::getID() { return id; }
int IFCI::getID() { return id; }

And now I am completly lost, because i do not have any idea what could be best practice to "link" the real objects to the Proxy Objects. One idea was to add the same vectors for IFCPrx* and IFBPrx* to class IFAI and also add a pointer from class IFBI and class IFCI to the real class B and class C Objects and do the lookup in the find methods by myself.I think it should be possible to have a maximum of one Proxy per real Object, otherwise i could create a new proxy for every findXXX call.
But I think that would be not the smartest way to implement this "problem".

Sorry for this absolute beginner question, a RTFM (with a rough hint on the right Chapter) or "see example XYZ" would help me a lot, but right now i am a little bit lost. :)

Comments

  • matthew
    matthew NL, Canada
    wald wrote: »
    ...
    And now I am completly lost, because i do not have any idea what could be best practice to "link" the real objects to the Proxy Objects. ...

    I suspect you are a bit confused about proxies, and Ice objects. A proxy is a bit like a pointer. Like a pointer, a proxy refers to an object, and like a pointer, you can have many pointers that refer to the same object. I suggest you start by reading my article "Proxies" in http://www.zeroc.com/newsletter/issue23.pdf. Once you have a read this, if you have further questions, please let me know!
  • Oh wow. Now I am confused ;)

    As I understand the article, a proxy is a representation of THE interface and not an instance of a class behind a interface. Now i completely lost track how i can get hold of a single instance of an object described by an interface.

    refering to my example above:
    On the Clientside i'd like to do something like:
    IFAPrx myA=...;        // A is (used) as a singleton, so a proxy should be fine i guess
    
    something_with_C_and_ICE *myC=myA.findC(17);
    something_with_C_and_ICE *myC2=myA.findC(38);
    something_with_B_and_ICE *myB=myA.findB(myC, 22);
    myB->someBMethod();
    

    So what would something_with_C_and_ICE be ? So I can read more documentation to get my little project done. ;)

    Is interface the right thing to do here ? Would classes be more appropriate for this ?
  • matthew
    matthew NL, Canada
    wald wrote: »
    Oh wow. Now I am confused ;)

    As I understand the article, a proxy is a representation of THE interface and not an instance of a class behind a interface.

    No, a proxy is handle, by which you can call on an Ice object. The object which is called upon is identified by the object identity, at a given location. This is similar to a C++ pointer.
    string s = "hello";
    string* p = &s;
    

    Here s is the object, and p is a "proxy" to the object s.
    Now i completely lost track how i can get hold of a single instance of an object described by an interface.

    The "instance" of the interface is identified by the identity, and in a typical deployment, the server endpoints.
    refering to my example above:
    On the Clientside i'd like to do something like:
    IFAPrx myA=...;        // A is (used) as a singleton, so a proxy should be fine i guess
    
    something_with_C_and_ICE *myC=myA.findC(17);
    something_with_C_and_ICE *myC2=myA.findC(38);
    something_with_B_and_ICE *myB=myA.findB(myC, 22);
    myB->someBMethod();
    

    In your case all of these would be proxies, not only myA.

    So what would something_with_C_and_ICE be ? So I can read more documentation to get my little project done. ;)

    Is interface the right thing to do here ? Would classes be more appropriate for this ?

    From a client point of view, as long as you are calling on the object by proxy, then whether or not the Ice object is an interface, or a class is irrelevant. Do not be confused by the following:
    class Foo
    {
    //...
    };
    
    interface Bar
    {
    Foo* getFoo();
    };
    

    In this example getFoo() returns a proxy to a Foo object.
    interface Bar
    {
    Foo getFoo();
    };
    

    In this case getFoo() returns a Foo object. Again, this is similar to C++:
    string* getString(); // returns a pointer to a string.
    string getString2(); // returns a string.
    
  • Ah thx a lot.
    I somehow "missed" the Object Incarnation Chapter of the documentation (shame on me) - with reading that and your explanation a lot of things became quite clear. Just one more question (serverside): Is it possible to obtain the proxy just by knowing the servant or is it a good idea to store the Proxy Object somewhere for later use after activation via _adapter‑>addWithUUID(servant) ?
  • xdm
    xdm La Coruña, Spain
    Hi Ralph,

    You can create a proxy if you know the identity that was used to register the servant with the adapter.
    Ice::Identity servantId ......;
    ObjectPrx proxy = _adapter->createProxy(servantId);
    

    The above code should return a proxy to the object register with identity servantId.

    If you add a servant to the adapter using addWithUUID Ice runtime generate a new Identity that is used for register the servant with the adapter, you can know this identity using ice_getIdentity on the returned proxy.

    Note that you can also store a proxy as a string using proxyToString method of the communicator and convert a string to a proxy using stringToProxy method also in Communicator.
  • Thx a lot ! Now i think i'm on the right track. :D