JNI C->java calls with multiple parameters

R

Rob Y.

I'm trying to design a JNI wrapper around a Java library (POI - excel
xls-format file creater), and have the basics working (thanks to
several of you who helped on the prior thread).

One last basic question, though. For my wrapper, I'd like to design
functions with multiple parameters. For example, I'd like to provide
a function to add a cell to a spreadsheet row, which in it's simplest
case needs to be passed the row and column numbers plus the string
text to insert there.

So I coded something like this:

// Add a new cell
public void addCell(int rownum, int colnum, String text)
{
HSSFRow r = sheet.getRow((short) rownum);
HSSFCell c = r.createCell((short) colnum);
c.setCellValue(text);
}

And in my C wrapper, I'm able to locate the method using the signature
below (two integer parameters and a string parameter - void return).

addCell = (*env)->GetMethodID(env, classptr, "addCell", "(IILjava/
lang/String;)V");

But I'm unable to find any examples of code that actually calls a
method like that. All the examples I've seen set up an object array
of strings and then fill the array up with strings (I've copied a
sample below). Ultimately, they just pass in the single array as the
sole parameter to their function.

Am I misguided in trying to set up methods that take multiple
parameters of various types? Should I just follow the examples and
pass in a bunch of strings all the time? Sorry for clueless
questions, but the Sun documentation contains precious few code
samples, and most of it is oriented toward the Java->C flavor of JNI.

I guess what I'm missing is how Java manages to garbage collect all
the objects created by the NewStringUTF calls. I don't see anything
explicitly releasing the strings in the example below, but I guess
since it's a C++ example, maybe the jobjectArray does it when it goes
out of scope. I'm working in C, so I assume I need to do something to
let the jvm know I'm done with the objects I create.

Here's a sample of 'standard' string array parameter passing I've
found. It seems to follow a cookbook. If somebody out there could
extend it into an example that calls a method with an integer and a
single string (not an array) as parameters, I think I could take it
from there. Thanks, rob.

jobjectArray str_array =
env->NewObjectArray(argc-2, env->FindClass("java/lang/String"),
jstr);

// Pass main arguments to Java
for( i = 2; i < argc; i++ ) {
jstr = env->NewStringUTF (argv);
if (jstr == 0) {
fprintf(stderr, "Out of memory\n");
return(1);
}
env->SetObjectArrayElement( str_array, i - 2, jstr);
}
 
R

Rob Y.

I went ahead and coded it like so, and the code works. So multiple
parameters of different types doesn't seem to be a problem.

I guess my only remaining question is am I leaking jstr's? If I just
call NewStringUTF on each loop iteration like below, how does the jvm
know that I'm not still using the prior jstr? Do I need to be calling
ReleaseStringUTFChars each time? Or some other function to destroy
the object? Sorry, but I just can't find a nice cross-referenced API
document anywhere that relates the various API calls to one another
(as in NewStringUTF, "see also..."). Is Sun's Java documentation that
bad, or am I just being that clueless?

jmethodID addCell;
jstring jstr;

...
addCell = (*env)->GetMethodID(env, classptr, "addCell", "(IILjava/
lang/String;)V");

for (row=0; row<10; row++) {
fprintf(stderr, "Adding row %d\n", row);
(*env)->CallVoidMethod(env, obj, addRow, row);
for (col=0; col<20; col++) {
fprintf(stderr, "Adding cell %d, %d, %s\n", row, col, text);
sprintf(text, "%d", 100*row+col);
jstr = (*env)->NewStringUTF(env, text);
(*env)->CallVoidMethod(env, obj, addCell, row, col, jstr);
}
}
 
A

Arne Vajhøj

Rob said:
I guess my only remaining question is am I leaking jstr's? If I just
call NewStringUTF on each loop iteration like below, how does the jvm
know that I'm not still using the prior jstr? Do I need to be calling
ReleaseStringUTFChars each time? Or some other function to destroy
the object? Sorry, but I just can't find a nice cross-referenced API
document anywhere that relates the various API calls to one another
(as in NewStringUTF, "see also..."). Is Sun's Java documentation that
bad, or am I just being that clueless?

jmethodID addCell;
jstring jstr;

...
addCell = (*env)->GetMethodID(env, classptr, "addCell", "(IILjava/
lang/String;)V");

for (row=0; row<10; row++) {
fprintf(stderr, "Adding row %d\n", row);
(*env)->CallVoidMethod(env, obj, addRow, row);
for (col=0; col<20; col++) {
fprintf(stderr, "Adding cell %d, %d, %s\n", row, col, text);
sprintf(text, "%d", 100*row+col);
jstr = (*env)->NewStringUTF(env, text);
(*env)->CallVoidMethod(env, obj, addCell, row, col, jstr);
}
}

Good question.

Some googling indicates that you need to do:

env->DeleteLocalRef(jstr);

to make it eligible for GC.

Arne
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

jni libjvm sigsegv 1
JNI: Calling Java Method with String as Parameter from C 5
JNI return jobjectArray 7
JNI Invocation API example 4
JNI C++ Wrapper 1
JNI Error in passing array 0
JNI 1
JNI error with JDK 1.5 0

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top