Go to the previous, next section.

Multiple Languages In One Address Space

With ILU version 2.0 or later, modules implemented in different programming languages can be mixed in the same address space, with ILU doing automatic translation between data representations. There are a number of things to consider when doing this; this section discusses some of them.

Dueling Runtimes

Some languages simply cannot be mixed in the same address space because their runtimes will conflict. ILU offers no solutions to this problem. Typical examples are two languages like Franz Allegro Common Lisp and DEC SRC Modula-3. They each implement a user-level threads package, and their implementations of threads probably cannot co-exist.

A possible solution to this problem, called the POSIX Portable Common Runtime (PPCR), is available from Xerox PARC, as ftp://ftp.parc.xerox.com/pub/ppcr/. It contains a basic runtime which can be used as the platform for a particular language implementation's runtime. Languages which use PPCR will have a lower chance of having conflicting runtimes.

Module Initialization

Module initialization really consists of two operations: interface initialization and object instantiation. The first operation initializes all the interfaces used or exported by the module; the second creates one or more true instances of objects to be used by other modules.

Generally, each ILU interface must be initialized. The process of doing this initialization varies from programming language to programming language. In ANSI C, ILU requires explicit calls to interface__Initialize() for interfaces being used, or interface__InitializeServer() for interfaces being exported. In C++, interface initialization is performed automatically, but at some indeterminate time before the first symbol from that interface is referenced from outside the interface. In Python or Common Lisp, interface initialization is performed automatically by the language at the time the module describing the interface is "loaded" into the address space.

In addition to initializing all interfaces being used or exported, a module must create one or more true object instances, to allow other modules to access it. Again, the specific way of doing this varies from programming language to programming language. Once the true instance has been created, it can be exported from the module by either publishing it, via the ILU simple binding system, or taking its string binding handle, and passing that outside the module for other modules to use.

When multiple languages are used in the same address space, each must be initialized according to the standards used for that programming language. This can be tricky when using both statically compiled and dynamically compiled languages together. Consider the case where Python and ANSI C are linked together. This use of Python may be as an extension language to a program written in C. In this case, the C code must do all initialization of modules written in C before calling into any Python module which might reference them. Similarly, Python initialization (import) of modules must occur before the C code can use them. See `ILUSRC/src/examples/multlang/' for an example of a situation of this sort.

In the other case, C true modules which are to be used from a Python program in the same address space must somehow be first loaded into that address space, then initialized. The loading is done by turning the C module into a Python extension module, and either linking it into the python image, or creating a dynamically loadable module from it. The initialization is done by then calling import on that module from within the Python interpreter. The extension module's initialization routine initializes all of its interfaces, creates one or more true objects, and exports them. After the import statement returns, the objects are available for finding (see next section) from within Python.

Finding Objects

Object instances may be located by calls on the variations of LookupObject and ObjectOfSBH that exist in the various language runtimes. LookupObject is implemented so that it first looks to see if the true object for the specified object ID is available in the local address space. If so, it returns a version of that object. Only if the object is not locally available does it perform external lookups in an attempt to locate the object. Note that for an object to be found via LookupObject, the true instance must first have been published via the implementation language ILU runtime's variant of PublishObject. If you do not want your objects published outside your address space, you should use ObjectOfSBH to find them.

Go to the previous, next section.