Based upon the documentation for CNI (Interoperating with C/C++) it looks like it should be possible to derive my own native CNI class from java::lang::Object. However when I compile the enclosed example there is a problem with the generated object, it contains no vtable for the class and there is an issue with creating the static variable class$. Am I doing something wrong or is this feature broken? The compilation output was obtained by commenting out the derivation of MyClass from java::lang::Object. Compiler output start++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ g++ -v -save-temps -o testit testit.cc -lgcj Reading specs from /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc- 3.3/install2/lib/gcc-lib/i686-pc-linux-gnu/3.3/specs Configured with: ../configure --enable-java-gc=boehm --enable-fast-character -- prefix=/home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2 : (reconfigured) ../configure --enable-threads=posix --enable-java-gc=boehm -- enable-fast-character --prefix=/home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc- 3.3/install2 --enable-shared --enable-languages=c++,java Thread model: posix gcc version 3.3 /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/lib/gcc-lib/i686- pc-linux-gnu/3.3/cc1plus -E -D__GNUG__=3 -quiet -v -D__GNUC__=3 - D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=0 -D_GNU_SOURCE testit.cc testit.ii ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/i686- pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/include/c++/3.3 /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc- 3.3/install2/include/c++/3.3/i686-pc-linux-gnu /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc- 3.3/install2/include/c++/3.3/backward /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/include /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/lib/gcc-lib/i686- pc-linux-gnu/3.3/include /usr/include End of search list. /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/lib/gcc-lib/i686- pc-linux-gnu/3.3/cc1plus -fpreprocessed testit.ii -quiet -dumpbase testit.cc - auxbase testit -version -o testit.s GNU C++ version 3.3 (i686-pc-linux-gnu) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.1 2.96-98). GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128433 as --traditional-format -V -Qy -o testit.o testit.s GNU assembler version 2.11.90.0.8 (i386-redhat-linux) using BFD version 2.11.90.0.8 /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/lib/gcc-lib/i686- pc-linux-gnu/3.3/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o testit /usr/lib/crt1.o /usr/lib/crti.o /home/scratch_scarp/shanes/xaud_work/C++/ GCC/gcc-3.3/install2/lib/gcc-lib/i686-pc-linux-gnu/3.3/crtbegin.o - L/home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/lib/gcc-lib/i686- pc-linux-gnu/3.3 -L/home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc- 3.3/install2/lib/gcc-lib/i686-pc-linux-gnu/3.3/../../.. testit.o -lgcj - lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s - lgcc /home/scratch_scarp/shanes/xaud_work/C++/GCC/gcc-3.3/install2/lib/gcc- lib/i686-pc-linux-gnu/3.3/crtend.o /usr/lib/crtn.o Compiler output end++++++++++++++++++++++++++++++++++++++++++++++++++++ Test Code start--------------------------------------------------------- #include <iostream> #include <string> #include <stdio.h> #include <gcj/cni.h> #include <java/lang/Object.h> #include <java/lang/System.h> using namespace std; class ::MyClass //: public java::lang::Object // <--Uncomment to see problem! { public: gnu::gcj::RawData * string; MyClass (); gnu::gcj::RawData * getText (); void printText (); }; ::MyClass::MyClass() { char* text = "44444"; string = (gnu::gcj::RawData * )text; } gnu::gcj::RawData * ::MyClass::getText () { return string; } void ::MyClass::printText () { printf("%s\n", (char*) string); } void PassTest(java::lang::String * text) { string stext((char *)JvGetStringChars(text),2*JvGetStringUTFLength(text)); cerr << "'" << stext << "'" << endl; } int main(int argc, char *argv[]) { JvCreateJavaVM(NULL); JvAttachCurrentThread(NULL, NULL); JvInitClass(&java::lang::System::class$); java::lang::String * string = JvNewStringLatin1("trace"); PassTest(string); MyClass * abc = new MyClass; abc->printText(); return 0; } Test code end------------------------------------------------------------
Actually, you can't make a subclass of Object (or any other Java class) that is entirely written in C++. The best you can do is make a Java class, all of whose methods are native. This is a limitation of the current implementation, anyway. There aren't any plans to change it at present. Could you suggest a change to the manual that makes this more clear?
Well it should not ICE either. Reopening because it currently ICE, maybe this ICE message should be changed to an error.
I can confirm this ICE on the mainline (20030708).
Related to bug 11006, in fact this is most likely the same bug as 11006.
Subject: Bug 11468 Author: reichelt Date: Fri Jun 23 15:59:51 2006 New Revision: 114937 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=114937 Log: PR c++/11468 * init.c (build_new_1): Handle error_mark_nodes returned by build_java_class_ref. (build_java_class_ref): Do not abort compilation, but return error_mark_node. Improve error message. Fix indentation. * g++.dg/other/java2.C: New test. Added: trunk/gcc/testsuite/g++.dg/other/java2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/init.c trunk/gcc/testsuite/ChangeLog
Fixed on mainline. Instead of bug.cc:55: internal compiler error: can't find class$ we now get a regular error with more information: bug.cc:55: error: can't find 'class$' in 'MyClass'