|
Comments
|
Today's Top SOA Links
Enterprise Managing Objects Between Java and C
Building the Java API on top of the native API
By: Hari Gottipati
Oct. 6, 2004 12:00 AM
If you've ever used JNI, you know how to manage the primitive data types between Java and the native language. As you delve into JNI, particularly when developing a Java API on top of a native API, you need to know how to manage the objects between Java and the native language. This article takes you to the next level and walks you through the step-by-step process of managing the objects between Java and C. Why JNI In addition, if you want to do some system-level programming with Java, you'll definitely end up using JNI somewhere. JNI is essential for bridging the gap between Java and the native functions. It allows you to write some code in a native language and then talk to that native code through Java. Real-Life Scenario Why Do You Need to Manage the Objects Between Java and C? Managing the Objects Between Java and C To maintain the same object in Java and C, create some object in Java and declare a long variable in it to hold the memory location of the object created in C. I'll illustrate this in detail with the mail example. The first part explains how to fill the Java object from C and the second part explains how to get the C object out of the Java object (to help you understand, I bifurcated each section into a Java side and a C side). Filling a Java Object from a C Object The following example discusses these steps in more detail:
public long nativeSession; public void native jniLogin(String server, String userName, String password);
public void login(String server, String userName, String password) {
jniLogin(server, userName, String password);
}
Listing 1 provides a nativeSession variable, which will hold the session object that actually gets created in C through the native method jniLogin. Once we create the session object in C, we'll fill this nativeSession variable that's declared in Listing 1 with the memory location of the C object. I'll discuss this in-depth later. I won't explain the step about creating the header file out of a Java file using the javah command (see Resources for this information), so I'll jump directly to the C implementation of this native method. Let's see the C implementation of the native method jniLogin:
Session msession = NULL;
connect(mserver, muserName, mpassword, &msession);
jlong sessionLocation = (jlong)msession; jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid =(*env)->GetFieldID(env, cls,"nativeSession","J");
(*env)->SetLongField(env,obj,fid,sessionLocation);
In line 8 of Listing 2, I'm declaring the Session(C) object. In line 14, to connect to a particular mail server, we're passing the values of the server, the user name, and the password to the connect method. If the given user name and password is valid, the msession object gets filled. Note that the function "Connect" is already defined in the C API of the mail server. Now we have the session object that logged into the server in C. In line 15 we're getting the memory location of the msession object. When you do (jlong)msession, it gives the memory location of the msession object. In line 20 we are getting the Java object that called this C function. In line 21, we're getting the long field(variable) "nativeSession" that we declared in Session(Java). In line 20 we're setting the long variable with the variable sessionLocation. Now the variable nativeSession of Session(Java) object holds the memory location of the msession(C) object. Getting the C Object Back Out of the Java Object The following example provides a clearer picture: public void native jniSendMail(Object o, String to, String subject, String body);
public void sendMail(String to, String subject, String body) {
jniSendMail(this, to, subject, body);
}
Let's say you wanted to send an e-mail with the session that logged in through the login method. For that we are passing the session object (with "this" keyword) to the jniSendMail method in Listing 3. Notice that session object has the nativeSession variable that holds the memory location of the native session object. With that we can send the e-mail. Let's see how we can get the native session back from this object in the next steps: jclass cls = (*env)->GetObjectClass(env, sessionobj);
jfieldID fid =(*env)->GetFieldID(env, cls,"nativeSession","J");
jlong session = (*env)->GetLongField(env,obj,fid);
Session * msession = (Session)session;
sendMail(msession, mto, msubject, mbody);
In line 14 of Listing 4, we're getting the Session(Java) class. In line 15, we're getting the variable nativeSession. Line 16 provides the value of the nativeSession variable that has the memory location of the native session. Line 18 has the C object from the memory location, since the long variable session holds the memory location of the native session object. When you typecast with (Session)session, it reads the object from the memory location. Now we have the C object. With this in line 19 we are calling the SendMail function with the values msession, mto, msubject, and mbody, which sends the e-mail to the address specified in the field "mto". Note that "SendMail" is the function that's already defined in the C API of the mail server. Resources Reader Feedback: Page 1 of 1
Your Feedback
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
|||||||||||||||||||||||||||||||||