Here is a sample project demonstrating the basics of building a CNI 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 sampSTL.o gcj -o sample \ sample.o sampNat.o sampSTL.o -lstdc++ --main=sample sample.o: sample.class gcj -c sample.class sample.class: sample.java gcj -C sample.java sample.h: sample.class gcjh sample sampNat.o: sample.h sampNat.cc g++ -c sampNat.cc clean: rm -f sample sample.o sampNat.o sampSTL.o sample.class sample.h ==> sampNat.cc <== #include #include "sample.h" //#include #include #include #include void sample::myNative(java::lang::String *s) { // 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(); // In version 2.96, the following line causes a link error // for a missing typeinfo unless this file is compiled // with '-fno-rtti'. This is corrected in version 3.0. java::lang::System::out->println(s); } ==> sampSTL.cc <== #include // Note that this function can not call any Java methods // that can throw exceptions, nor can it 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) { 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"); } }