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)