Jump to content

The SOM Interface Definition Language: Difference between revisions

From EDM2
Prokushev (talk | contribs)
No edit summary
Prokushev (talk | contribs)
mNo edit summary
Line 1: Line 1:
by [[Prokushev]]
by [[Prokushev]]


In [[Introduction to SOM|previous]] article we briefly looked at SOM.
In [[Introduction to SOM|previous]] article we briefly looked at [[SOM]].
Now we'll try to define our class interface.
Now we'll try to define our class interface.


Line 8: Line 8:
to produce DEF file you can run
to produce DEF file you can run
  sc -s"def" somcls.idl
  sc -s"def" somcls.idl
[[SOM Compiler]] uses [[emitter]] to produce corresponding language binding. You can create new bindings using [[Emitter Framework]].
[[SOM Compiler]] uses [[emitter]] to produce corresponding language binding. You can create new bindings [[emitter]] using [[Emitter Framework]].


First of all, think about your class. What it must do? Define them in
First of all, think about your class. What it must do? Define them in
terms of object. Propose attributes and methods of class.
terms of object. Propose attributes and methods of class.


Ok. Imagine, we need class to have access to Java objects. Let's write
Ok. Imagine, we need class to have access to [[Java]] objects. Let's write
class interface in terms of Interface Definition Language.
class interface in terms of Interface Definition Language.


  #include <somobj.idl>
  #include <somobj.idl>
   
   
  interface JavaObject : SOMObject
  interface JavaObject : [[SOMObject]]
  {
  {
   implementation
   implementation
   {
   {
     somDefaultInit: override;
     [[somDefaultInit]]: override;
     // Init Java machine (if no current) and create Java object
     // Init Java machine (if no current) and create Java object
     somDefaultDestruct: override;
     [[somDefaultDestruct]]: override;
     // Destruct Java object and close Java machine (if needed)
     // Destruct Java object and close Java machine (if needed)
   }
   }
Line 31: Line 31:
As you can see, no many problems. Syntax of IDL too closest to C-like
As you can see, no many problems. Syntax of IDL too closest to C-like
languages. First thing you need is to include definitions of parent
languages. First thing you need is to include definitions of parent
classes. In our case it is '''SOMObject''' definition. Generic Java object
classes. In our case it is '''[[SOMObject]]''' definition. Generic [[Java]] object
doesn't need to have any methods. Only thing '''JavaObject''' will do its
doesn't need to have any methods. Only thing '''[[JavaObject]]''' will do its
check for existance of Java Machine and execution of it if required.
check for existance of [[Java Virtual Machine]] and execution of it if required.
On object destruction checks is Java Machine still required will be
On object destruction checks is [[Java Virtual Machine]] still required will be
done and it will be destroed if not required. Also same constructor
done and it will be destroed if not required. Also same constructor
and destructor will call corresponding constructor and destructor
and destructor will call corresponding constructor and destructor
Line 41: Line 41:
Classic IDL file contains definitons like
Classic IDL file contains definitons like


  interface <object> : <parent>
  interface <class> : <parent_class>
  {
  {
   attribute <type> <name>
   attribute <type> <name>
Line 48: Line 48:
  }
  }


As I known [http://www.omg.org OMG] IDL doesn't support methods override. SOM IDL has
As I known [http://www.omg.org OMG] IDL doesn't support methods override. [[SOM]] IDL has
such feature (and incompatability with OMG CORBA). This is done via
such feature (and incompatability with OMG CORBA). This is done via
keyword '''implementation'''. To solve problems with other IDL compilers
keyword '''implementation'''. To solve problems with other IDL compilers
Line 56: Line 56:
  #include <somobj.idl>
  #include <somobj.idl>
   
   
  interface JavaObject : SOMObject
  interface JavaObject : [[SOMObject]]
  {
  {
   
   
Line 62: Line 62:
   implementation
   implementation
   {
   {
     somDefaultInit: override;
     [[somDefaultInit]]: override;
     // Init Java machine (if no current) and create Java object
     // Init [[Java Virtual Machine]] (if no current) and create [[Java]] object
     somDefaultDestruct: override;
     [[somDefaultDestruct]]: override;
     // Destruct Java object and close Java machine (if needed)
     // Destruct [[Java]] object and close [[Java Virtual Machine]] (if needed)
   }
   }
   #endif
   #endif
Line 77: Line 77:
Ok. Let's stop talking about syntax things (you always can read documentation)
Ok. Let's stop talking about syntax things (you always can read documentation)
and try to create IDL from
and try to create IDL from
Java class.
[[Java]] class.


As a first step we'll create SOM class interface for java.lang.Object.
As a first step we'll create [[SOM]] class interface for java.lang.Object.
It is can be done with help of javah tool.
It is can be done with help of javah tool.


Line 191: Line 191:
  end
  end
  say '}'
  say '}'
As result, you'll have following:

Revision as of 08:06, 24 December 2004

by Prokushev

In previous article we briefly looked at SOM. Now we'll try to define our class interface.

Interface Definition Language (IDL) is core of System Object Model. All classes has definition of its interface via IDL. With help of SOM Compiler IDL file can be translated to various formats, including various language bindings. For example, to produce C header you can run

sc -s"h" somcls.idl

to produce DEF file you can run

sc -s"def" somcls.idl

SOM Compiler uses emitter to produce corresponding language binding. You can create new bindings emitter using Emitter Framework.

First of all, think about your class. What it must do? Define them in terms of object. Propose attributes and methods of class.

Ok. Imagine, we need class to have access to Java objects. Let's write class interface in terms of Interface Definition Language.

#include <somobj.idl>

interface JavaObject : SOMObject
{
  implementation
  {
    somDefaultInit: override;
    // Init Java machine (if no current) and create Java object
    somDefaultDestruct: override;
    // Destruct Java object and close Java machine (if needed)
  }
}

As you can see, no many problems. Syntax of IDL too closest to C-like languages. First thing you need is to include definitions of parent classes. In our case it is SOMObject definition. Generic Java object doesn't need to have any methods. Only thing JavaObject will do its check for existance of Java Virtual Machine and execution of it if required. On object destruction checks is Java Virtual Machine still required will be done and it will be destroed if not required. Also same constructor and destructor will call corresponding constructor and destructor of Java object.

Classic IDL file contains definitons like

interface <class> : <parent_class>
{
  attribute <type> <name>

  <type> <method>(<parameters>)
}

As I known OMG IDL doesn't support methods override. SOM IDL has such feature (and incompatability with OMG CORBA). This is done via keyword implementation. To solve problems with other IDL compilers such part must be wrapped to #ifdef structure:


#include <somobj.idl>

interface JavaObject : SOMObject
{

  #ifdef __SOMIDL__
  implementation
  {
    somDefaultInit: override;
    // Init Java Virtual Machine (if no current) and create Java object
    somDefaultDestruct: override;
    // Destruct Java object and close Java Virtual Machine (if needed)
  }
  #endif
}

Such approach well known in C-world, but also have some problems. For example, IDL of Document Object Model (DOM) (Yes, W3C DOM uses same IDL as SOM and CORBA) has attribute implementation. As result, SOM Compiler has some problems with IDL compilation.

Ok. Let's stop talking about syntax things (you always can read documentation) and try to create IDL from Java class.

As a first step we'll create SOM class interface for java.lang.Object. It is can be done with help of javah tool.

javah -jni java.lang.Object

As result you'll have such file:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class java_lang_Object */

#ifndef _Included_java_lang_Object
#define _Included_java_lang_Object
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     java_lang_Object
 * Method:    hashCode
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_java_lang_Object_hashCode
  (JNIEnv *, jobject);

/*
 * Class:     java_lang_Object
 * Method:    notify
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_java_lang_Object_notify
  (JNIEnv *, jobject);

/*
 * Class:     java_lang_Object
 * Method:    notifyAll
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_java_lang_Object_notifyAll
  (JNIEnv *, jobject);

/*
 * Class:     java_lang_Object
 * Method:    registerNatives
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_java_lang_Object_registerNatives
  (JNIEnv *, jclass);

/*
 * Class:     java_lang_Object
 * Method:    wait
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_java_lang_Object_wait
  (JNIEnv *, jobject, jlong);

/*
 * Class:     java_lang_Object
 * Method:    getClass
 * Signature: ()Ljava/lang/Class;
 */
JNIEXPORT jclass JNICALL Java_java_lang_Object_getClass
  (JNIEnv *, jobject);

/*
 * Class:     java_lang_Object
 * Method:    clone
 * Signature: ()Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL Java_java_lang_Object_clone
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

So, this header can be used to generate actual class interface using this script:

/* REXX - our best dog */

do while lines('java_lang_Object.h')
  s=linein('java_lang_Object.h');
  parse value s with x 'Header for class' name '*/'
  if name\= then
  do
    classname=strip(name)
    say '#include <JavaObject.idl>'
    say 
    say 'interface '||classname||' : JavaObject'
    say '{'
  end
  parse value s with x 'Method:' name
  if name\= then
  do
    /* skip 3 lines */
    s=linein('java_lang_Object.h');
    s=linein('java_lang_Object.h');
    s=linein('java_lang_Object.h');
    s2=linein('java_lang_Object.h');
    interpret("parse value s with 'JNIEXPORT' type 'JNICALL Java_"||classname||"_' name")
    name=strip(name)
    s2=strip(s2)
    parse value s2 with start 'JNIEnv *, jobject' end
    s2=start||end
    parse value s2 with x ', ' y
    if x='(' then s2='('||y
    say '  '||type||name||' '||s2
  end
end
say '}'

As result, you'll have following: