469,304 Members | 2,018 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,304 developers. It's quick & easy.

Using JNI to access C++ class member functions

34
Hi I'm trying to write a JNI for a linkedlist class I wrote in C++. Basically I have a header file with the class definition and a C++ file with the definition of the class member functions.

I have a record file llist.h

Expand|Select|Wrap|Line Numbers
  1. class llist
  2. {
  3.     private:
  4.         record        *start;
  5.         char          filename[16];
  6.         int           readfile();
  7.         int           writefile();
  8.         record *      reverse(record *);
  9.         void          cleanup();
  10.  
  11.     public:
  12.         llist();
  13.         llist(char[]);
  14.         ~llist();
  15.         int addRecord(char[], char[], int, char[]);
  16.         int printRecord(char[]);
  17.         int modifyRecord(char[], char[], int, char[]);
  18.         void printAllRecords();
  19.         int deleteRecord(char[]);
  20.         void reverse();
  21. };
then the C++ code:

Expand|Select|Wrap|Line Numbers
  1. int llist::readfile()
  2. {
  3.  
  4. }
  5.  
  6. int llist::writefile()
  7. {
  8.  
  9. }
  10.  
  11. llist::llist()
  12. {
  13.  
  14. }
  15.  
  16. llist::llist(char name[])
  17. {
  18.  
  19. }
  20.  
  21. llist::~llist()
  22. {
  23.  
  24. }
  25.  
  26. int llist::addRecord(char name[], char address[], int yearofbirth, char telno[])
  27. {
  28. ;
  29. }
  30.  
  31. int llist::deleteRecord(char name[])
  32. {
  33.  
  34. }
  35.  
  36. int llist::modifyRecord(char name[], char address[], char telno[])
  37. {
  38.  
  39. }
  40.  
  41. void llist::printAll()
  42. {
  43.  
  44. }
  45.  
  46.  
  47. record::record()
  48. {
  49. }
Then I need a Java Code. For the JNI, I will create a method to display a menu that allows a user to add, delete, modify, and display records. The JNI will call the functions written in C++. But what is the code I put in the Java file to access the class functions? Normally, if it's just a regular function and not part of a class member, it would go something like:

Expand|Select|Wrap|Line Numbers
  1. class UserInterface {
  2.     public native int addRecord(char [] name, char [] address, ....etc);
  3.     ...
  4.     ....
  5.     and so on
  6.  
  7.    static {
  8.         System.loadLibrary("UserInterface");
  9.     }
  10.  
  11.     code....
  12.     .................
  13. }
Dec 4 '07 #1
6 11563
JosAH
11,448 Expert 8TB
That's exactly how it's done. The javah tool generates the necessary header file
given your compiled .class file that contains the 'native' definitions. The generated
.h file contains the prototypes of the C/C++ functions you have to create yourself.

Those functions normally act as wrappers for your real functions. Compile and
link the stuff into a .dll (or .so file if you're on unix) and off you go.

kind regards,

Jos
Dec 4 '07 #2
jthep
34
So what if I wanted to call the constructor llist() to create a list and initialize all members of the class definition? public native Ilist(); gives me a syntax error since I have no return type. Since both are declared as private, I wrote the constructor and destructor so that it calls the readfile() and writefile() respectively. I'm not directly calling those two functions in the java file, do I still need a native line in there?

As for the header file would it resemble a class? From the steps I read on how to use the JNI was to create the java class first, then the header file with the function definition and it would be something like this for the addRecord...

Expand|Select|Wrap|Line Numbers
  1. class llist_H{
  2.  
  3. JNIEXPORT jint JNICALL Java_UserInterface_addRecord(..............)
  4.   (JNIEnv *, jobject, jint);
  5. ...
  6. ....
  7. }
Dec 4 '07 #3
JosAH
11,448 Expert 8TB
So what if I wanted to call the constructor llist() to create a list and initialize all members of the class definition? public native Ilist(); gives me a syntax error since I have no return type. Since both are declared as private, I wrote the constructor and destructor so that it calls the readfile() and writefile() respectively. I'm not directly calling those two functions in the java file, do I still need a native line in there?
You cannot call a C++ ctor from Java directly; you have to craft another native
method (in C++) that creates your C++ object for you. Java and C++ are two
separate worlds; even a pointer to a C++ object doesn't mean anything to Java
(and vice versa). You need a native 'initialize()' method in Java to set up your
C++ list object.

kind regards,

Jos
Dec 4 '07 #4
jthep
34
Thanks Jos! Okay....so something like the void initializer(); method in C++ would call the constructor and same thing with the destructor.

Expand|Select|Wrap|Line Numbers
  1. void initializer()
  2. {
  3.     llist();
  4. }
and

Expand|Select|Wrap|Line Numbers
  1. void initializer(char [] filename)
  2. {
  3.     llist(filename);
  4. }
Then call the function in java by public native void initializer(); Since the constructor is public, I can declare it anywhere.

Regards,
Jthep
Dec 4 '07 #5
JosAH
11,448 Expert 8TB
Thanks Jos! Okay....so something like the void initializer(); method in C++ would call the constructor and same thing with the destructor.

Expand|Select|Wrap|Line Numbers
  1. void initializer()
  2. {
  3.     llist();
  4. }
and

Expand|Select|Wrap|Line Numbers
  1. void initializer(char [] filename)
  2. {
  3.     llist(filename);
  4. }
Then call the function in java by public native void initializer(); Since the constructor is public, I can declare it anywhere.

Regards,
Jthep
Yep, true. I normally use the Java class as a real wrapper around a C++ class.
You need to convert a C++ pointer to a, say, Java long (or small byte[]) and
vice versa.

When your Java code creates the Java wrapper, it creates a C++ object (using
that initializitation native method) and stores the C++ pointer to the object as a
long (or byte[]). It's up to you to implement an explicit 'delete()' method in Java
or let it go with the flow and get rid of the wrapped C++ object when/if the Java
object is finalized and its finalize() method is called (that's where you destroy
the wrapped C++ object then).

That way the rest of your Java code doesn't even 'know' that its talking to a C++
object. Internally your Java class just passes that secret pointer back and forth.

kind regards,

Jos
Dec 4 '07 #6
jthep
34
Thanks. Btw, when compiling and running this code on UNIX, is there a way to run javax.swing.JOptionPane on UNIX? I had some old java projects that I did on eclipse using JOptionPane, I could compile and run in eclipse but I can only compile in UNIX. I couldn't run it without it giving me the UnsatisfiedLinkedError.

Regards,
Jthep
Dec 5 '07 #7

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

2 posts views Thread by Kevin Saff | last post: by
7 posts views Thread by Wolfgang Jeltsch | last post: by
3 posts views Thread by quo | last post: by
1 post views Thread by Bryan Parkoff | last post: by
3 posts views Thread by Richard Webb | last post: by
11 posts views Thread by Brent Ritchie | last post: by
2 posts views Thread by Niklas Norrthon | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by harlem98 | last post: by
1 post views Thread by Geralt96 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.