围绕C main函数编写JNI包装器 [英] writing a JNI wrapper around a C main function

查看:81
本文介绍了围绕C main函数编写JNI包装器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须围绕现有的C源代码编写JNI包装,以便可以从Java调用它们.但是大多数C源代码都接受命令行参数(argc和argv)并广泛使用它们.我可以通过什么方式将在Java中捕获的字符串args []传递给C函数,而对C源文件的更改却很少?

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?

我相信,作为JNI包装器的一部分,我必须用C语言编写一个Java代码调用的函数.

I believe that as part of the JNI wrappers, I have to write a function in C that is called by the Java code.

推荐答案

可以肯定,您必须编写一个Java代码调用的C函数.

For sure, you'll have to write a C function called by the Java code.

从Radiodef指向的答案中可以看出,该函数将收到一个jobjectarray,因为Java String[]jni中表示为jobjectArray.

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.

在该函数中,您将必须分配一个C数组,用于在其char **argv参数中存储旧版main函数期望的所有char *指针.

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.

您将在该数组中存储已分配的指针,以便能够立即释放JNI对象.您可以避免使用这些malloc,但是要以将JNI资源存储在另一个数组中以供进一步发布为代价,所以我认为这不是一个好主意.

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.

请记住,旧版主要功能的约定是第一个arg(索引0)是程序名".您将不得不伪造它.

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;
}

这篇关于围绕C main函数编写JNI包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆