Forum Stats

  • 3,836,939 Users
  • 2,262,206 Discussions
  • 7,900,149 Comments

Discussions

Compiling C++ classes on Linux

843829
843829 Member Posts: 49,201
edited Jun 12, 2001 3:53PM in Java Native Interface (JNI)
Thanks in advance for your help!
I'm trying to compile a C++ class (that calls another class) with JNI. It compiles but the functions don't seem to be in the .o file.
The HelloWorld example runs fine.
Any ideas?

Comments

  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    More information would be helpful.

    When you say 'not in the .o file' what does that mean? Did you look at it with a linux tool and it doesn't show the function signatures? Or did you try to load a lib in java an got a method not found error?

    And I haven't looked a linux but on every unix I have used a .o file is usually an object file and has nothing to do with a shared library. And java uses shared libraries not object files.
  • 843829
    843829 Member Posts: 49,201
    Did have a long, detailed message, but it didn't post, for some reason.
    There's a class written in C++ which I want to use, Token. I have a wrapper Java class, Tokenizer. The Tokenizer C++ class I defined holds a Token object, as a data member.
    When running java, the .so is found, but the method isn't, what I get is:
    UnsatisfiedLinkError: getType
    so I checked the shared library file, and the method doesn't show in it:
    nm -s libtoken.so
    ... <methods from Token, not Tokenizer>
    I tried also:
    nm -s tokenizer.o
    00000000 t gcc2_compiled.
    When running
    nm -s token.o, I get the full list of methods.

    I just noticed, the C++ class and ata members are defined in the .h file. Am I supposed to define the class and data members in the generated .h file?
    Here is the compilation process:

    g++ -c -I/usr/local/java/jdk1.3/include -I/usr/local/java/jdk1.3/include/linux token.cc
    g++ -c -I/usr/local/java/jdk1.3/include
    -I/usr/local/java/jdk1.3/include/linux tokenizer.cc
    ld -shared -o libtoken.so token.o tokenizer.o
    java -Djava.library.path=.:/usr/local/java/jdk1.3/lib/i386/:/usr/local/lib ex3 symboltableitem.cmm
    Exception in thread "main" java.lang.UnsatisfiedLinkError: getType
    at Tokenizer.getType(Native Method)
    at Parser.declaration(Parser.java:69)
    at Parser.declaration(Parser.java:42)
    at ex3.main(ex3.java:33)


    Tried also compiling this way, and then Java doesn't find 'main':

    g++ -I/usr/local/java/jdk1.3/include -I/usr/local/java/jdk1.3/include/linux token.cc tokenizer.cc -Xlinker -G -o libtoken.so

    java -Djava.library.path=.:/usr/local/java/jdk1.3/lib/i386/:/usr/local/lib ex3 symboltableitem.cmm
    Exception in thread "main" java.lang.UnsatisfiedLinkError: /a/fs-01/grad/amigo/Compilers/Ex3/libtoken.so: /a/fs-01/grad/amigo/Compilers/Ex3/libtoken.so: undefin
    ed symbol: main
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1382)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1306)
    at java.lang.Runtime.loadLibrary0(Runtime.java:749)
    at java.lang.System.loadLibrary(System.java:820)
    at ex3.main(ex3.java:22)


    I'm just about to give up and re-write the class in Java. But that's not what JNI is supposed to do :)
    Thanks,
    ami
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    First a clarification: JNI uses C not C++.

    So if you are trying to call a C++ class method directly it will not work. And if you don't have extern "C" in front of the C method and compile it with a C++ compiler it will not work.

    And lastly you might keep in mind that JNI should not be used for small processing tasks. The overhead of calling the JNI method will eat up any time saved by writing the method in C. This is why the String methods are written in java.
  • 843829
    843829 Member Posts: 49,201
    Thank you!!!
    The C++ class was already written and debugged, so I thought of using it as is. Could have saved a lot of agony by translating it, even though that's up to compilers to do translations. That's what happens when I try to save time :)
    Ami
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    You can use it.

    You just can't call the methods directly from java. That is what the extern "C" is for.
This discussion has been closed.