Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2006

Tip: Looking for answers? Try searching our database.

JNI: instace object C++ from Java

Thread view: 
flack - 21 Mar 2006 16:07 GMT
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!
Gordon Beaton - 21 Mar 2006 16:28 GMT
> 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

Signature

[  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

flack - 21 Mar 2006 18:49 GMT
Are you sure that there isn't some trick to use c++ methods?

The doubt is coming when I have read this post:
http://groups.google.it/group/comp.lang.java.programmer/browse_thread/thread/b4b
fa7d78f205066/3ac2b31639123573?lnk=st&q=instance+c%2B%2B+object+in+java+jni&rnum
=19&hl=it#3ac2b31639123573


What do you think about that?
Gordon Beaton - 21 Mar 2006 19:02 GMT
> 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

Signature

[  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

Roedy Green - 21 Mar 2006 19:20 GMT
>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.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Gordon Beaton - 21 Mar 2006 20:02 GMT
> 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

Signature

[  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

Roedy Green - 21 Mar 2006 23:40 GMT
>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.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

unodivoi - 27 Mar 2006 02:19 GMT
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!!!!!
Gordon Beaton - 27 Mar 2006 09:30 GMT
> 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

Signature

[  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

flack - 27 Mar 2006 14:09 GMT
>   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!
Gordon Beaton - 27 Mar 2006 14:52 GMT
> Then, how can I call "methodA" (myCppObject.methodA) in native code?

Obviously you have to cast the object back:

 myCppObject = (CppObject*)ptr;

/gordon

Signature

[  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

flack - 30 Mar 2006 22:56 GMT
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);
 
}
Gordon Beaton - 31 Mar 2006 08:32 GMT
> 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

Signature

[  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

unodivoi - 31 Mar 2006 09:22 GMT
> 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"
Gordon Beaton - 31 Mar 2006 12:17 GMT
> 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

Signature

[  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

Roedy Green - 21 Mar 2006 19:14 GMT
>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
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.