TOBA

Native Function Example


Let's go through a quick example. Here is a class that allows you to write to an arbitrary unix file descriptor:
    public class writer {
        int fd;

        public writer(int num) {
            fd = num;
        }

        public int write(String str) {
            byte[] data = new byte[str.length()];
            str.getBytes(0, str.length(), data, 0);
            return write(data);
        }
        public native int write(byte[] data);

        public static void main(String[] args) {
            writer w = new writer(1);
            w.write("Hello World!\n");
        }
    }
The method write is a native function which we will implement to do the actual writing. The src code above compiles to the class file writer.class. Running toba on this class file generates a header file writer.h with the following content:
    % toba -C writer.java
    % cat writer.h

    /*  writer.h -- from Java class writer  */
    /*  created by Toba  */

    #ifndef h_writer
    #define h_writer

    #define init_writer() (void)0

    Void init_i_rfxGD(Object,Int);
    Int  write_S_kG3VC(Object,Object);
    Int  write_ab_LJfqP(Object,Object);
    Void main_aS_0Tfn5(Object);

    struct mt_writer {
        struct {int s; Object(*f)(Object);} getClass__zh19H;
        struct {int s; Int(*f)(Object);} hashCode__8wJNW;
        struct {int s; Boolean(*f)(Object,Object);} equals_O_Ba6e0;
        struct {int s; Object(*f)(Object);} clone__dslwm;
        struct {int s; Object(*f)(Object);} toString__4d9OF;
        struct {int s; Void(*f)(Object);} notify__ne4bk;
        struct {int s; Void(*f)(Object);} notifyAll__iTnlk;
        struct {int s; Void(*f)(Object,Long);} wait_l_1Iito;
        struct {int s; Void(*f)(Object,Long,Int);} wait_li_07Ea2;
        struct {int s; Void(*f)(Object);} wait__Zlr2b;
        struct {int s; Void(*f)(Object);} finalize__UKxhs;
        struct {int s; Void(*f)(Object);} init__AAyKx;
        struct {int s; Void(*f)(Object,Int);} init_i_rfxGD;
        struct {int s; Int(*f)(Object,Object);} write_S_kG3VC;
        struct {int s; Int(*f)(Object,Object);} write_ab_LJfqP;
    };

    extern struct cl_writer {
        struct class C;
        struct mt_writer M;
    } cl_writer;

    struct in_writer {
        struct cl_writer *class;
        struct monitor *monitor;
        Int fd;
    };

    #endif /* h_writer */
The native function we have to implement is Int write_ab_LJfqP(Object,Object);. As a first test we generate a native C file that does nothing:
    #include "toba.h"
    #include "writer.h"

    /* writer write ([B)I */
    Int write_ab_LJfqP(Object Harg1, Object Harg2)
    {
        struct in_writer *this = (struct in_writer *)Harg1;

        printf("writer/write not implemented yet\n");
        exit(1);
    }
All that is left now is to fill in the necessary functionality in place of the current body:
    #include <errno.h>
    #include "toba.h"
    #include "runtime.h"
    #include "writer.h"

    /* writer write ([B)I */
    Int write_ab_LJfqP(Object Harg1, Object Harg2)
    {
        struct in_writer *this = (struct in_writer *)Harg1;
        struct barray *buf = (struct barray *)Harg2;
        int res;
	extern int errno;

        if(!buf)
            throwNullPointerException("null argument to write");

        res = write(this->fd, buf->data, buf->length);
        if(res == -1)
            throwIOException("error writing", errno);

        return res;
    }
The native routine can be compiled along with the generated code for the class:
    % toba -I../sumatra/runtime native.c writer.class
    % a.out
    Hello World!
    %
The include path directive was needed to get the runtime/runtime.h include file which has the prototypes for the throw routines.


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