JNI: instace object C++ from Java

Discussion in 'Java' started by flack, Mar 21, 2006.

  1. flack

    flack Guest

    I'm a newby about JNI.
    I have an application write in C++ and I have to migrate it to Java.
    I have seen that JNI permit to call c++ methods that return only
    primitive type as string or int.
    My question is simple: if I have a C++ class that we call "ClassA", can
    I instance an object "ClassA" in Java that run the constructor and
    where can I call the methods of "ClassA" as I was in C++?

    I want something like this in Java:

    jClassA a;
    jClassB b
    b = h.methodClassA(int d);


    Can I do that?

    Thank you!
     
    flack, Mar 21, 2006
    #1
    1. Advertising

  2. On 21 Mar 2006 07:07:46 -0800, flack wrote:
    > I have an application write in C++ and I have to migrate it to Java.
    > I have seen that JNI permit to call c++ methods that return only
    > primitive type as string or int.


    Not just primitives: you can pass *any* Java types (primitives or
    Objects) between Java and native code. Please note that String is not
    a primitive.


    > My question is simple: if I have a C++ class that we call "ClassA",
    > can I instance an object "ClassA" in Java that run the constructor
    > and where can I call the methods of "ClassA" as I was in C++?


    No. JNI doesn't let you invoke arbitrary methods written in C or C++,
    or create C++ objects.

    JNI is a mechanism that lets you implement some (or all) of a Java
    class's methods in C or C++. Furthermore those methods must have been
    written with the intent of being called through JNI, i.e. they must
    use signatures and data types as defined by JNI, and follow a specific
    calling convention.

    However from those native methods you are free to create C++ objects
    and invoke their methods however you like.

    JNI also lets your native code invoke any Java methods or
    constructors, or access fields in Java objects.

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 21, 2006
    #2
    1. Advertising

  3. flack

    flack Guest

    flack, Mar 21, 2006
    #3
  4. On 21 Mar 2006 09:49:18 -0800, flack wrote:
    > Are you sure that there isn't some trick to use c++ methods?


    Did you actually read the thread you referred to?

    The example shows that it is possible to call a native method, and
    _from_there_ create the C++ object. If you read my earlier answer,
    you'll see that this is exactly what I said you must do.

    The only "trick" here is that the C++ pointer is passed back to Java
    as an int (although I would recommend a long).

    You still can't use the object from Java. To do anything meaningful
    with it you must first pass it back to a native method, then cast it
    to whatever object it once was.

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 21, 2006
    #4
  5. flack

    Roedy Green Guest

    On 21 Mar 2006 07:07:46 -0800, "flack" <>
    wrote, quoted or indirectly quoted someone who said :

    >jClassA a;
    >jClassB b
    >b = h.methodClassA(int d);
    >


    Normally, Java calls C/C++, but you can do the reverse. Normally you
    just pass primitives back and forth. On the C++ side, you can create a
    Java object with the JNI API and populate its fields and return it,
    most commonly a String.

    You can also create C++ objects and use them on the C++ side. They
    mean nothing on the Java side so you can't bring them over into Java
    without converting them to Java objects first.


    see http://mindprod.com/jgloss/jni.html
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Mar 21, 2006
    #5
  6. flack

    Roedy Green Guest

    On 21 Mar 2006 16:28:45 +0100, Gordon Beaton <> wrote,
    quoted or indirectly quoted someone who said :

    >No. JNI doesn't let you invoke arbitrary methods written in C or C++,
    >or create C++ objects.


    More precisely, from Java you cannot create arbitrary C or C++
    objects, but of course you can create them on the C++ side.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Mar 21, 2006
    #6
  7. On Tue, 21 Mar 2006 18:20:19 GMT, Roedy Green wrote:
    > More precisely, from Java you cannot create arbitrary C or C++
    > objects, but of course you can create them on the C++ side.


    Which is exactly what I wrote a couple of sentences later.

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 21, 2006
    #7
  8. flack

    Roedy Green Guest

    On 21 Mar 2006 20:02:08 +0100, Gordon Beaton <> wrote,
    quoted or indirectly quoted someone who said :

    >Which is exactly what I wrote a couple of sentences later.


    I thought your explanation was going over OP's head. So I decided to
    restate it in a more elementary way.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Mar 21, 2006
    #8
  9. flack

    unodivoi Guest

    First, thanks to all for response.

    I haven't understand how I can manage the object pointer.
    Can someone do an explicit example?
    We can suppose that we have in java this code:

    public class JObject {

    private final long objectPtr = 0;
    private native void objectCreate();

    public static void main(String[] args){
    JObject my = new JObject();
    my.objectCreate();
    }
    }



    In native code what will we write?

    JNIEXPORT void JNICALL
    Java_objectManager_objectCreate(JNIEnv *env, jobject obj)
    {

    CppObject *ptr = 0;
    CppObject myCppObject;
    ptr = &myCppObject;

    ?????????????????? :-(

    }


    Can someone rewrite correctly the above code with the target to
    instance a C++ class (CppObject) and return to Java its pointer?

    Thank you!!!!!
     
    unodivoi, Mar 27, 2006
    #9
  10. On 26 Mar 2006 17:19:39 -0800, unodivoi wrote:
    > Can someone rewrite correctly the above code with the target to
    > instance a C++ class (CppObject) and return to Java its pointer?


    It's trivial if you declare the native method so that it *returns* the
    long:

    private native long objectCreate();

    Then:

    return (jlong)&myCppObject;

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 27, 2006
    #10
  11. flack

    flack Guest

    > private native long objectCreate();
    >
    > Then:
    >
    > return (jlong)&myCppObject;


    Ok, this cast is simple.
    But suppose that I must call a method of my object.
    I have to call in java a function that give as member the long variable
    pointer:
    private native void objectMethodA(objectPtr);

    public class JObject {

    private final long objectPtr = 0;
    private native long objectCreate();
    private native void objectMethodA(long objectPtr);

    public static void main(String[] args){
    JObject my = new JObject();
    my.objectCreate();
    my.objectMethodA(objectPtr);
    }

    }


    Then, how can I call "methodA" (myCppObject.methodA) in native code?

    JNIEXPORT jlong JNICALL
    Java_objectManager_objectMethodA(JNIEnv *env, jobject obj, jlong ptr)
    {

    ????????????????????

    }


    JNIEXPORT jlong JNICALL
    Java_objectManager_objectCreate(JNIEnv *env, jobject obj)
    {
    CppObject *ptr = 0;
    CppObject myCppObject;
    ptr = &myCppObject;
    return (jlong)&ptr;
    }



    Thanks!
     
    flack, Mar 27, 2006
    #11
  12. On 27 Mar 2006 05:09:58 -0800, flack wrote:
    > Then, how can I call "methodA" (myCppObject.methodA) in native code?


    Obviously you have to cast the object back:

    myCppObject = (CppObject*)ptr;

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 27, 2006
    #12
  13. flack

    flack Guest

    Java console give me this error: unsatisfiedLinkError:
    JAxObjectManager.axObjectManagerConstructor() ect.....

    I don't understand where is the error..
    can someone help me?
    I use:
    - jvm--> j9 ibm
    - pocket pc 2003
    - evc4

    I use this link:
    255#"\Programmi\J9\MIDP20\bin\j9.exe"
    "-jcl:midp20:loadLibrary=AxomStudentVCEmbeddedDLL"
    "-Xbootclasspath:\Programmi\J9\MIDP20\lib\jclMidp20\jclMidp20.jxe"
    "-cp" "\Programmi\J9\MIDP20\examples\Axom2\axom.jar" "JAxObjectManager"

    --------------------------------
    --------------------------------

    class JAxObjectManager {

    // salvo il puntatore all'oggetto allocato nel codice nativo
    private static long axObjectManagerPtr = 0;
    private native long axObjectManagerConstructor();
    private native void jgetRootIndex(long axObjectManagerPtr);


    public static void main(String[] args){

    JAxObjectManager my = new JAxObjectManager();
    axObjectManagerPtr = my.axObjectManagerConstructor();
    my.jgetRootIndex(axObjectManagerPtr);

    //System.out.println("Dopo: "+axObjectManagerPtr);

    }

    }



    --------------------
    --------------------
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class JAxObjectManager */

    #ifndef _Included_JAxObjectManager
    #define _Included_JAxObjectManager
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
    * Class: JAxObjectManager
    * Method: axObjectManagerConstructor
    * Signature: ()J
    */
    JNIEXPORT jlong JNICALL
    Java_JAxObjectManager_axObjectManagerConstructor
    (JNIEnv *, jobject);

    /*
    * Class: JAxObjectManager
    * Method: jgetRootIndex
    * Signature: (J)V
    */
    JNIEXPORT void JNICALL Java_JAxObjectManager_jgetRootIndex
    (JNIEnv *, jobject, jlong);

    #ifdef __cplusplus
    }
    #endif
    #endif

    --------------------
    --------------------


    #define WIN32
    #include <jni.h>
    #include "windows.h"

    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <stdexcept>
    #include <string>
    #include <axom/axobjectmanager.h>

    ect..... other include...


    #include "JAxObjectManager.h"

    JNIEXPORT jlong JNICALL
    Java_JAxObjectManager_axObjectManagerConstructor(JNIEnv *env, jobject
    obj)
    {

    AxObjectManager *axObjectManagerPtr = 0;
    AxObjectManager myAxom;
    axObjectManagerPtr = &myAxom;
    return (jlong)axObjectManagerPtr;

    }


    JNIEXPORT void JNICALL
    Java_JAxObjectManager_jgetRootIndex(JNIEnv *env, jobject obj, jlong
    axObjectManagerPtrLong)
    {

    AxObjectManager* myAxom;
    myAxom = (AxObjectManager*) axObjectManagerPtrLong;
    //(myAxom).getRootIndex();
    AxCommandExpand *beforeExpand = new
    AxCommandExpand((*myAxom).getRootIndex());
    (*myAxom).executeCommand(*beforeExpand);
    TEST("expand (empty)",
    beforeExpand->getChildrenIndexes().size()==0);

    }
     
    flack, Mar 30, 2006
    #13
  14. flack

    unodivoi Guest


    > I don't know j9, but AFAICT you failed to load the DLL in your code
    > (i.e. System.loadLibrary() or equivalent).



    i run dll "AxomStudentVCEmbeddedDLL" from link path, there isn't a
    System.loadLibrary() in the code, it's not supported:

    255#"\Programmi\J9\MIDP20\bin\j9.exe"
    "-jcl:midp20:loadLibrary=AxomStudentVCEmbeddedDLL"
    "-Xbootclasspath:\Programmi\J9\MIDP20\lib\jclMidp20\jclMidp20.jxe"
    "-cp" "\Programmi\J9\MIDP20\examples\Axom2\axom.jar" "JAxObjectManager"
     
    unodivoi, Mar 31, 2006
    #14
  15. On 30 Mar 2006 13:56:37 -0800, flack wrote:
    > Java console give me this error: unsatisfiedLinkError:
    > JAxObjectManager.axObjectManagerConstructor() ect.....
    >
    > I don't understand where is the error..


    I don't know j9, but AFAICT you failed to load the DLL in your code
    (i.e. System.loadLibrary() or equivalent).

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 31, 2006
    #15
  16. On 31 Mar 2006 00:22:39 -0800, unodivoi wrote:
    > i run dll "AxomStudentVCEmbeddedDLL" from link path, there isn't a
    > System.loadLibrary() in the code, it's not supported:


    This article on using JNI with j9 seems to disagree with you:

    http://www.cs.hku.hk/~fyp05016/kyng/ibm_j9.htm

    Other posts I've seen claim that JNI itself isn't supported by early
    versions of j9. Perhaps you need a later version that supports JNI and
    thus has System.loadLibrary(). Again, I don't know j9 or midp...

    Other things to check:

    Is there (or has there been) a package declaration in your java
    source? If so, there is a chance that the generated native symbol
    names are wrong as a result.

    Have you confirmed with a binary inspection tool that the native
    symbols in the DLL *exactly* match those in the generated header file?

    Failing that, post the complete and exact error message, it may
    contain some more clues.

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Mar 31, 2006
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Hunsley

    IBM's JNI fails where Sun's JNI works

    Alex Hunsley, Nov 3, 2003, in forum: Java
    Replies:
    4
    Views:
    886
    Alex Hunsley
    Nov 4, 2003
  2. Pasturel Jean-Louis

    Porting JNI Windows under JNI LINUX + Wine ?

    Pasturel Jean-Louis, Feb 29, 2004, in forum: Java
    Replies:
    5
    Views:
    947
    Pasturel Jean-Louis
    Mar 3, 2004
  3. vasanth
    Replies:
    0
    Views:
    2,786
    vasanth
    Jan 25, 2005
  4. Fabio Pliger

    check instace already running...

    Fabio Pliger, Apr 9, 2005, in forum: Python
    Replies:
    3
    Views:
    465
    Fabio Pliger
    Apr 10, 2005
  5. Stefan Salewski
    Replies:
    5
    Views:
    151
    Jeremy Bopp
    Oct 7, 2010
Loading...

Share This Page