From fc1dbfce13b3de36a1507f8db1f7138e79696fa0 Mon Sep 17 00:00:00 2001 From: bothner Date: Wed, 5 May 1999 23:15:04 +0000 Subject: [PATCH] * doc/cni.sgml: Document RawData. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26791 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/doc/cni.sgml | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/libjava/doc/cni.sgml b/libjava/doc/cni.sgml index 0255431..fac01db 100644 --- a/libjava/doc/cni.sgml +++ b/libjava/doc/cni.sgml @@ -369,6 +369,98 @@ to private C++ fields and methods, but other fields and methods are mapped to public fields and methods. +Non-Java fields + +When you write a Java wrapper around an existing library, that library +will often allocate and manage its own data structures. These are +objects that are not Java Objects; +instead they are usually C struct instances. +Typically, you will write a Java class, and use native CNI methods +which call functions in the C library. The problem is how to get +from the Java wrapper object to the C struct instances. +The obvious solution is to add a field to the Java object that +points to the C structure. The problem is that there is no Java +type that we can give to this field. +The GCJ solution is to define a special dummy class +gnu.gcj.RawData. This can be used as the type for fields, +parameters, array elements, or local variables in Java code. +It means that the field or variable is a pointer to a non-Java object. +Nothing else is known about it, so it corresponds to a +(void*) declaration is C or C++ code. + +The garbage collector will ignore a field that has type +gnu.gcj.RawData. You are responsible for +freeing the C data structure when you are done with it, and +performing any necessary cleanups. In most cases, you should +use a finalize method, and have it call +the library's cleanup routine. Also, the C data structure +should not contain a pointer back to the Java object, since +the garbage collector will not know about the pointer. +If you need to save a pointer to a Java object inside some +non-Java data structure, you first need to pin +or globalize the pointer; there is no CNI function +to do this yet. +(From the point of view of the +implementation, a gnu.gcj.RawData value is +the same as an integer that has the same size as a pointer.) + +Here is an example where we create a Java wrapper around C stdio: + +import gnu.gcj.RawData; + +public class StdioFile +{ + private RawData file; + public StdioFile (RawData file) { this.file = file; } + public StdioFile (String name, String mode) + throws FileNotFoundException + { init(name, mode); } + private native void init (String name, String mode) + throws FileNotFoundException; + public native int getc(); + public native int close(); + protected native void finalize(); +} + +This is the CNI implementation: + +jint +StdioFile::getc() +{ + return getc((FILE*) file); +} + +jint +StdioFile::close() +{ + return fclose((FILE*) file); +} + +void +StdioFile::init(jstring name, jstring mode) +{ + int cname_len = JvGetStringUTFLength (name); + int cmode_len = JvGetStringUTFLength (mode); + char cname[cname_len + 1]; + char cmode[cmode_len + 1]; + JvGetStringUTFRegion (name, 0, name->length(), cname); + JvGetStringUTFRegion (mode, 0, mode->length(), cmode); + cname[cname_len] = '\0'; + cmode[cmode_len] = '\0'; + file = (gnu::gcj::RawData*) fopen(cname, cmode); + if (file == NULL) + JvThrow(new java::lang::FileNotFoundException(name)); +} + +void +StdioFile::finalize() +{ + fclose((FILE*) file); +} + + + + Arrays -- 2.7.4