TOBA

Using Native C Code with Toba


While Toba is designed primarily for programs written in Java, the addition of native functions written in C is not difficult. However, the interface differs from the Sun native interface.

This page notes some key points of the native code interface, but it is not a complete tutorial. The prospective native coder should also study the data structures defined in toba.h, found in the runtime directory of the Toba package. Some examples of native code may be found in the runtime directory; these files implement portions of the Java API.

Datatypes

The include file toba.h defines general types and data structures. Each method parameter is one of the types Int, Long, Float, Double, or Object. Return types are any of those or Void. Other integral types are passed as Int.

Object pointers represent all reference types including arrays. All object structures begin with a class pointer; for any object pointer o, the expression

(((struct in_generic *)o)->class)
produces a Class pointer to the structure containing information about the class. This structure is described in toba.h.

Arrays are indicated by the IS_ARRAY bit in the flags field of the class structure. For arrays, the elemclass field points to the class structure giving the array element type. If the array elements are a Java primitive type, the IS_PRIMITIVE flag is set in elemclass->flags.

Data structures specific to a particular class are defined in the classname.h file, with underscores replacing periods in the class name. The class structure is a global variable named cl_classname; it contains class information, instance function pointers, and any static variables. The structure of an object instance is defined by struct in_classname.

Method Names

The C code for a native method has a name that is derived from the method name. The C name includes a hash code that also factors in the class name and method signature. The hash code differentiates overloaded methods and like-named methods of different classes. The name hashing also allows native implementations of methods having names (such as häagen_dazs()) that are illegal in C.

The C form of a name is found by compiling with toba -C the Java code that declares the native method. This produces a classname.h file containing the proper prototype.

If a native method is declared synchronized, a wrapper function with the stated name is generated; it calls the actual native function, having the same name but prefixed by sy_.

Method Code

Each native code file begins by including general and class-specific definitions:

#include <toba.h>
#include "
classname.h"
The classname.h file must be present when native code is compiled. This is arranged automatically if the Java and C code are built together by a command such as toba maincode.java native.c.

Every native method is a C function. The actual code can be very simple. Instance methods have an implicit initial this parameter, but there are no other hidden parameters.

Here is an example of a simple but complete native static function:

Int getpid__9zIGm(void)
{
return getpid();
}

Exceptions can be thrown by calling athrow(e) where e is the actual exception object. The hard part is constructing this object; try writing that first in Java and looking at the corresponding C code produced by toba -C.

Class Initialization

Every class must be initialized before it is used. Generally, this is done by Toba automatically. However, it is up to the programmer to make sure that a class has been initialized before it is accessed from native code. A class must be initialized by calling the initclass function at least once before the first use of any field or method in the class. It is safe to call initclass on the same class more than once.

Static Initialization

If the class of a native method contains initialization code in the form of a <clinit> method, this code must be called on entry to any static method. The easiest way to accomplish this is to begin every static method with

init_classname();
which expands to an initialization call only if the class actually needs it.

Initialization code is not needed in instance functions. If an instance of a class exists, as is necessary to call such a function, then the class must already have been initialized.

Static Final Variables

Static final variables that are initialized with compile-time constant expressions appear to native methods to be uninitialized. We are investigating possible solutions to this problem.

More Information

The Toba library contains a number of helper functions written to support the generated code and the API library. These helper functions are available for use by native methods.

For existing methods written to the Sun interface, a conversion guide notes some correspondences between Sun and Toba helper functions.

A simple example illustrates the coding of a native method.


index | usage | differences | native code | implementation | porting | releases | installation || home
http://www.cs.arizona.edu/sumatra/toba/doc/native.html (July, 1998)