Reputation: 103
I have to write JNI wrappers around existing C source codes so that they can be called from Java. But most of the C source codes take in command line arguments (argc and argv) and use them extensively. Is there any way that I can pass the string args[] that I capture in Java, to the C function with very minimal changes to the C source file?
I believe that as part of the JNI wrappers, I have to write a function in C that is called by the Java code.
Upvotes: 2
Views: 1304
Reputation: 7620
For sure, you'll have to write a C function called by the Java code.
As seen in the answer pointed to by Radiodef, that function will receive a jobjectarray
, as a java String[]
is represented in jni
as a jobjectArray
.
In the function, you will have to malloc a C arrays, for storing all the char* pointers that your legacy main
function is expecting in it's char **argv
argument.
You will store in that array malloced pointers, in order to be able to release the JNI objects immediately. You may avoid those malloc, but at the cost of storing JNI resources in another array for further release, so I don't think it's a goo idea.
Remember that the convention for legacy main functions is that the first arg (index 0) is the 'program name'. You will have to fake it.
void MyJNIFunction(JNIEnv *env, jobject object, jobjectArray stringArray) {
// Get the number of args
jsize ArgCount = (*env)->GetArrayLength(env, stringArray);
// malloc the array of char* to be passed to the legacy main
char ** argv = malloc(sizeof(char*)*(ArgCount+1)); // +1 for fake program name at index 0
argv[ 0 ] = "MyProgramName";
int i;
for ( i = 0; i < ArgCount; ++i ) {
jstring string = (jstring)((*env)->GetObjectArrayElement(env, stringArray, i));
const char *cstring = (*env)->GetStringUTFChars(env, string, 0);
argv[ i + 1 ] = strdup( cstring );
(*env)->ReleaseStringUTFChars(env, string, cstring );
(*env)->DeleteLocalRef(env, string );
}
// call the legacy "main" function
LegacyMain( ArgCount + 1, argv );
// cleanup
for( i = 0; i < ArgCount; ++i ) free( argv[ i + 1 ] );
free( argv );
return;
}
Upvotes: 6