Using OMG IDL with ILU
ILU also supports the use of the interface definition language OMG IDL, defined
by the Object Management Group (OMG) for their Common Object Request Broker
Architecture (CORBA). OMG IDL uses a C++-like syntax, so it may be easier for
Python and C++ programmers to use than ILU ISL.
A D V E R T I S E M E N T
Unfortunately, CORBA doesn't
include some of the concepts in ILU, such as garbage collection for transient
objects, or OPTIONAL types, so not every ILU interface can be
expressed in OMG IDL, but many of them can. For example, here is the OMG IDL
version of the Tutorial interface:
module Tutorial {
exception DivideByZero {};
interface Calculator {
// Set the value of the calculator to `v'
void SetValue (in double v);
// Return the value of the calculator
double GetValue ();
// Adds `v' to the calculator's value
void Add (in double v);
// Subtracts `v' from the calculator's value
void Subtract (in double v);
// Multiplies the calculator's value by `v'
void Multiply (in double v);
// Divides the calculator's value by `v'
void Divide (in double v) raises (DivideByZero);
};
interface Factory {
// Create and return an instance of a Calculator object
Calculator CreateCalculator();
};
};
This can be used with the python-stubber:
% python-stubber Tutorial.idl
client stubs for interface "Tutorial" to Tutorial.py ...
server stubs for interface "Tutorial" to Tutorial__skel.py ...
%
This will be a bit slower than running the python-stubber on the
equivalent ISL file, as the program works by converting the OMG IDL into ISL,
then compiling from the ISL description. OMG IDL interfaces can be checked by
running the OMG IDL-to-ILU ISL converter, idl2isl, directly:
% idl2isl Tutorial.idl
INTERFACE Tutorial;
EXCEPTION DivideByZero;
TYPE Calculator = OBJECT OPTIONAL
METHODS
SetValue (v : REAL),
GetValue () : REAL,
Add (v : REAL),
Subtract (v : REAL),
Multiply (v : REAL),
Divide (v : REAL)
RAISES DivideByZero END
END;
TYPE Factory = OBJECT OPTIONAL
METHODS
CreateCalculator () : Calculator
END;
%
You will notice that the ISL interface generated by idl2isl is a
bit different, in that the object type modifier OPTIONAL is used in
the description of the Calculator and Factory types.
This is because CORBA has the notion that any object type instance passed as a
parameter or return value (or field in an array, or element of a sequence, etc.)
may be None, instead of being a valid instance pointer. Thus, when
working with OMG IDL descriptions of your interfaces, it is necessary to check
the return type of methods like Tutorial.Factory.CreateCalculator
to see that a valid object reference has been returned, before using the object.
ISL allows you to have these CORBA-style objects, by using the OPTIONAL
modifier in the declaration of an object type, but it also allows object
pointers which can't be None. By default ILU object instances may
not be None.
Transient and Permanent Objects
Keen-eyed readers will have seen that the Calculator type in
`Tutorial.isl' is marked with the modifier COLLECTIBLE, while
the Factory type is not. ILU differentiates between two kinds of
objects, which we call transient and permanent.
Transient objects are typically created for a specific use, and typically
have a fixed lifetime. They often have state associated with them. They are
frequently used to represent some ongoing computation or operation.
Permanent objects are usually expected to be around forever (or until some
activity not captured by a programming concept terminates). Permanent objects
are often gateways to some sort of service, or represent some external piece of
data, such as a cell in a spreadsheet, or a file on a disk somewhere. They are
often stateless; when they do have state, it is typically backed by some form of
stable storage, as they have to be available across crashes of their server
program.
ILU provides an automatic system for distributed garbage collection of
transient objects; that is, of removing them from everyone's address space when
everyone is done with them. This uses the underlying garbage collection
techniques of the particular programming language being used. With Python, the
ILU garbage collector works in conjunction with the Python collector; with ANSI
C, we use the extremely primitive collector provided for C; that is, when the
process terminates, the objects are collected. To indicate to ILU that a
particular object type is to be treated as transient, you mark the object type
specification, in the ISL, with the keyword COLLECTIBLE.
For permanent objects, like the Tutorial.Factory object type,
the ILU Python support will maintain a reference to the instance, preventing the
Python collector from collecting it.
Using ILU with Tkinter
Python comes with a module called Tkinter, which is an interface
to John Ousterhout's Tk user interface system. When you use both ILU and Tkinter
together in a program, you should call the ilu_tk main loop to
block and dispatch requests, instead of the ilu main loop. To
illustrate this, here is a version of the server2.py program which
puts up a Tk button. When the user presses the button, the server exits. Notice
that instead of calling ilu.RunMainLoop() to block indefinitely,
the program calls ilu_tk.RunMainLoop(). This call allows both Tk
and ILU events to be handled when neither a Tk callback nor an ILU method call
is active.
# server3.py -- a program that runs a Tutorial.Calculator server
# Puts up a Tk button to kill it with.
# import the ilu_tk module first, so that
# initialization happens in the right order:
import ilu_tk
# now import the other modules...
import ilu, FactoryImpl2, sys, Tkinter
def main(argv):
def quit():
sys.exit(0)
if (len(argv) < 2):
print "Usage: python server3.py SERVER-ID"
sys.exit(1)
theServer = ilu.CreateServer (argv[1])
theFactory = FactoryImpl2.Factory ("theFactory", theServer)
theFactory.IluPublish()
# Now we put up a Tk button so that the user can kill the
# server by pressing the button
f = Tkinter.Frame() ; Tkinter.Pack.config(f)
b = Tkinter.Button (f, {'text' : theFactory.IluObjectID(),\
'command': quit})
b.pack ({'side': 'left', 'fill': 'both'})
# Then we wait in the ilu_tk mainloop, instead of either
# the ILU mainloop or the Tkinter mainloop
ilu_tk.RunMainLoop()
main(sys.argv)
General ILU Info
The Inter-Language Unification system (ILU) is a multi-language object interface
system. The object interfaces provided by ILU hide implementation distinctions
between different languages, between different address spaces, and between
operating system types. ILU can be used to build multi-lingual object-oriented
libraries ("class libraries") with well-specified language-independent
interfaces. It can also be used to implement distributed systems. It can also be
used to define and document interfaces between the modules of non-distributed
programs.
The 2.0 release of ILU contains support for the programming languages ANSI C,
C++, Modula-3, Python, and Common Lisp. It has been installed on many flavors of
UNIX, including SPARC machines running SunOS 4.1.3 and Solaris 2, SGI MIPS
machines running IRIX 5.2, Intel 486 machines running Linux 1.1.78, DEC Alpha
machines with OSF/1, IBM RS/6000 machines running AIX, and HP machines running
HP/UX. It runs on Microsoft Windows 3.1, Windows 95, and Windows NT
environments. It supports both threaded and non-threaded operation. Since one of
the implementation goals of ILU is to maximize compatibility with existing open
standards, ILU provides support for use of the OMG CORBA IDL interface
description language, and can be thought of as a CORBA ORB system (though with
omissions from and extensions to the CORBA spec). As another result, ILU
includes a self-contained implementation of ONC RPC.
|