Definition of GNOME::Unknown

The GNOME::Unknown interface is defined as follows:

module GNOME {
	interface Unknown {
		void ref ();

		void unref ();
		
		Object query_interface (in string repoid);
	};
};

GNOME::Unknown has two main uses. its first two functions are used to maintain a reference count of the references to the interface. The query_interface method is used to ask an object what CORBA interfaces it supports, as well as to switch between the various interfaces an object supports.

Reference counting allows objects to manage their lifetimes. Unlike COM, CORBA has no build-in mechanism for this. Thus, if a CORBA server dies, its clients will be notified of its destruction by a CORBA_SYSTEM_EXCEPTION-exception when sending requests to the now non-existent object.

The idea of using reference counting is an idea which is at the basis of COM Distributed Object System: every time you get a reference to an interface, you must increase the reference count for this interface by calling ref(), and every time you have finished using the interface, you should unref() it. The object simply maintains an internal counter which is increased by each call to ref and decreased by each call to unref. This allows the object to know when it is not necessary to stay alive anymore. When the count reaches zero, the object may decide to destroy itself. Note: interfaces acquired through the query_interface have their reference count already increased. The must be unref'ed, however.

When writing code, you should be careful to balance ref's and unref's. If there are too few unref, effectively you have a memory leak, especially if the component is implemented in a shared library. Especially, make sure components are released (unref'ed) before going out of scope. On the other hand, if there are too many unref's, you may kill the component prematurely, while your client code needs it.

The query_interface allows you to 'browse' the interfaces supported by some object. Let's imagine I have a word processor capable of embedding Bonobo components, but which can also be embedded itself, in other containers. This program is thus both a container and a component. This means that it must support both the GNOME::embeddable and the GNOME::container interfaces.

The idea is that if you ask for a reference to the CORBA::Object which represents this application, you will get a pointer to its GNOME::Unknown interface. From here on, you may ask the object for either its GNOME::Container interface or the GNOME::Embeddable interface with query_interface to get an object reference to the implementation of the requested interface. For example, to get the GNOME::Embeddable interface:

CORBA_Object obj_unknown;
CORBA_Object obj_embeddable;

obj_unknown = CosNaming_NameService_resolve (orb, "Word97", &ev);

obj_embeddable = GNOME_Unknown_query_interface (obj_unknown, "IDL:GNOME/embeddable:1.0", &ev);

This system also allows you to work around versioning problems. Let's imagine I have defined a new embeddable interface. this interface's name will be IDL:GNOME/embeddable:2.0 which means that if you also preserve the old IDL:GNOME/embeddable:1.0 interface on your object, any container willing to embed your component will do so without any problem, provided it supports either 1.0 or 2.0 interfaces. embeddable objects. This allows you to make your applications evolve in time, without breaking backward compatibility. Of course, you may not change existing interfaces, as this will lead to unexpected behavior.

A sample extendable implementation of the GNOME::Unknown interface is detailed in the next section.