This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[Patch] Re: CNI compile error
- To: java-patches at gcc dot gnu dot org
- Subject: [Patch] Re: CNI compile error
- From: Glenn Chambers <gchamber at bright dot net>
- Date: Fri, 29 Jun 2001 21:49:15 -0400
Oops. Sent the below to the wrong list...
>[on java@gcc.gnu.org] I wrote:
>
>>GCJ Team: Should I update cni-2.txt to document the 3.0 status, or
>>keep it as-is, since it more-or-less accurately documents the non-FSF
>>Red Hat compiler release? If I keep cni-2.txt as-is, I'll create a
>>cni-3.txt with the new information.
I've put together the patch on the basis of not going out of the way
to document non-FSF releases. If you want it the other way, feel free
to do so, or ask me to.
I don't have any paperwork on file, but I think these are still trivial
enough to pass muster...
2001-06-29 Glenn Chambers <gchamber@bright.net>
* cni-2.txt: Updated for 3.0 exception issues.
* jni-comp.txt: Added.
* faq.html: Update cni and invocation answers; link to Kaffe.org.
Index: cni-2.txt
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/java/cni-2.txt,v
retrieving revision 1.3
diff -u -r1.3 cni-2.txt
--- cni-2.txt 2001/02/08 17:34:35 1.3
+++ cni-2.txt 2001/06/30 01:16:06
@@ -1,12 +1,15 @@
Here is a sample project demonstrating the basics of building a CNI
-application with a prerelease snapshot of GCJ version 2.96.
+application with GCJ version 3.0. Note that the 'sampSTL' gyrations
+are necessary only if you use code within your CNI methods that
+could conceivably catch a C++ exception.
It assumes that you have installed the binaries in a directory
in your path.
==> Makefile <==
-sample: sample.o sampNat.o
- gcj -o sample sample.o sampNat.o -lstdc++ --main=sample
+sample: sample.o sampNat.o sampSTL.o
+ gcj -o sample \
+ sample.o sampNat.o sampSTL.o -lstdc++ --main=sample
sample.o: sample.class
gcj -c sample.class
@@ -17,42 +20,65 @@
sample.h: sample.class
gcjh sample
+sampSTL.o: sample.h sampSTL.cc
+ g++ -fno-rtti -c sampSTL.cc
+
sampNat.o: sample.h sampNat.cc
g++ -fno-rtti -c sampNat.cc
clean:
- rm -f sample sample.o sampNat.o sample.class sample.h
+ rm -f sample sample.o sampNat.o sampSTL.o sample.class sample.h
==> sampNat.cc <==
#include <gcj/cni.h>
#include "sample.h"
-#include <stream.h>
+//#include <stream.h>
#include <java/io/PrintStream.h>
#include <java/lang/System.h>
#include <java/lang/String.h>
+extern void callSTLcode();
+
void sample::myNative(java::lang::String *s)
{
- cout << "Hello, C++" << endl;
+ // Due to the new exception-handling code implemented
+ // in gcc version 3.0, the following line will fail
+ // with an error about mixing exception types between
+ // C++ and Java. Factoring this code out into a
+ // seperate function that does not include any Java
+ // code solves the problem.
+// cout << "Hello, C++" << endl;
+ callSTLcode();
// The following line causes a link error for a missing typeinfo
// unless this file is compiled with '-fno-rtti'
java::lang::System::out->println(s);
}
+==> sampSTL.cc <==
+#include <stream.h>
+
+// Note that this function can not call any Java methods,
+// nor can the file include cni.h.
+
+void callSTLcode()
+{
+ cout << "Hello, C++" << endl;
+}
+
==> sample.java <==
public class sample {
public native void myNative(String s);
- public void myJava() {
- String s = "Hello, Java";
+ public void myJava(String s) {
+ s = s + ", Java";
System.out.println(s);
}
public static void main(String args[]) {
sample x = new sample();
- x.myJava();
+ x.myJava("Hello");
x.myNative("Hello, Java (from C++)");
- x.myJava();
+ x.myJava("Goodbye");
}
}
Index: cni-2.txt
===================================================================
--- /dev/null Tue May 5 16:32:27 1998
+++ jni-comp.txt Thu Jun 28 22:39:27 2001
@@ -0,0 +1,101 @@
+This is a trivial example of a JNI native method intended
+to provide a comparision with the GCJ CNI example. The
+source files are identical to the jni-kaffe example; only
+the Makefile has changed.
+
+This was built using GCJ 3.0 on a RedHat 6.0 system, and
+run by installing libsampNat.so in a directory in the
+library path and running the sample executable.
+
+Note that the current implementation will not work if you
+simply link the native calls into the executable and omit
+the loadLibrary call from the application. This is due
+to the implementation of JNI method lookup in
+java/lang/natRuntime.cc.
+
+==> Makefile <==
+
+all: sample libsampNat.so
+
+libsampNat.so: sampNat.o
+ gcc -shared -o libsampNat.so sampNat.o
+
+sampNat.o: sampNat.c sample.h
+ gcc -c sampNat.c
+
+sample.h: sample.class
+ gcjh -jni sample
+
+sample.class: sample.java
+ gcj -C sample.java
+
+sample: sample.class
+ gcj -fjni -o sample sample.class --main=sample
+
+clean:
+ rm -f sample.h sample.class sample sampNat.o libsampNat.so
+
+==> sampNat.c <==
+
+#include <jni.h>
+#include "sample.h"
+#include <stdio.h>
+
+void Java_sample_myNative(JNIEnv* env, jobject this, jstring s)
+{
+ jclass cls;
+ jfieldID fid;
+ jobject obj;
+ jmethodID mid;
+
+ printf("From C\n");
+
+ cls = (*env)->FindClass(env, "java/lang/System");
+ if (cls == 0) {
+ printf("java/lang/System lookup failed\n");
+ return;
+ }
+ fid = (*env)->GetStaticFieldID(env, cls, "out", "Ljava/io/PrintStream;");
+ if (fid == 0) {
+ printf("java/lang/System::out lookup failed\n");
+ return;
+ }
+ obj = (*env)->GetStaticObjectField(env, cls, fid);
+ if (obj == 0) {
+ printf("GetStaticObjectField call failed\n");
+ return;
+ }
+ cls = (*env)->GetObjectClass(env, obj);
+ if (cls == 0) {
+ printf("GetObjectClass(out) failed\n");
+ return;
+ }
+ mid = (*env)->GetMethodID(env, cls, "println", "(Ljava/lang/String;)V");
+ if (mid == 0) {
+ printf("println method lookup failed\n");
+ return;
+ }
+ (*env)->CallVoidMethod(env, obj, mid, s);
+}
+
+==> sample.java <==
+
+public class sample {
+ public native void myNative(String s);
+
+ public void myJava(String s) {
+ s = s + ", Java";
+ System.out.println(s);
+ }
+
+ public static void main(String args[]) {
+ sample x = new sample();
+ x.myJava("Hello");
+ x.myNative("Hello, Java (from C)");
+ x.myJava("Goodbye");
+ }
+
+ static {
+ System.loadLibrary("sampNat");
+ }
+}
+
+
Index: faq.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/java/faq.html,v
retrieving revision 1.42
diff -u -r1.42 faq.html
--- faq.html 2001/04/17 02:07:47 1.42
+++ faq.html 2001/06/30 01:42:03
@@ -742,9 +742,13 @@
<h3><a name="6_1"></a>6.1 Are there any examples of how to use
CNI?</h3>
<blockquote>
<p>Glenn Chambers has created a couple
- of trivial examples <a href="cni-1.txt">here</a> and <a
href="cni-2.txt">here</a>.
+ of trivial examples for
+ <a href="cni-1.txt">version 2.95</a>
+ and <a href="cni-2.txt">version 3.0</a>.
As a comparision, <a href="jni-kaffe.txt">here</a>
- is the same example as a JNI application.
+ is the same example as a JNI application using
+ <a href="http://www.kaffe.org">Kaffe</a>. The same code will
+ work with GCJ, as shown <a href="jni-comp.txt">here</a>.
</p>
<p>
Note that you must compile the C++ files used for CNI with the
@@ -771,7 +775,14 @@
<p>
Of course, it is possible to instantiate Java classes
and call back into them from C++ code: the only requirement is that
- your application must have been started from Java "main" method.
+ your application must have been started from Java "main" method.
+ </p>
+ <p>
+ THe current development sources have initial support for a
+ CNI-based invocation interface as well as the traditional
+ JNI-based API.
+ See <a
href="http://gcc.gnu.org/ml/java-patches/2001-q2/msg00263.html">this
message</a>
+ for the patch, and <a
href="http://gcc.gnu.org/ml/java-patches/2001-q2/msg00224.html">this
one</a> for details on how to use the CNI interface.
</p>
</blockquote>
</dl>
-- Glenn Chambers
-- Toledo, Ohio
-- gchamber@bright.net