java-native-interface - 围绕 C 主函数编写 JNI 包装器

标签 java-native-interface

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

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

最佳答案

当然,您必须编写一个由 Java 代码调用的 C 函数。

正如在 Radiodef 指出的答案中看到的那样,该函数将接收一个 jobjectarray,因为 java String[]jni 中表示> 作为 jobjectArray

在该函数中,您必须 malloc 一个 C 数组,用于存储您的遗留 main 函数期望在它的 char **argv 中的所有 char* 指针争论。

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

请记住,遗留主要功能的约定是第一个 arg(索引 0)是“程序名称”。你将不得不伪造它。

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

关于java-native-interface - 围绕 C 主函数编写 JNI 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20258134/

相关文章:

Android,对于 JNI,是否应该在 InputMethodService 中调用 System.loadLibrary?

java - 运算符 reinterpret_cast<const uint8_t*> 后出现错误 "core dumped"

java - C获取函数地址

java - JNI,在 jobect 和 jthrowable 之间转换

android ndk 多点触控?

缺少 x86 架构的 Android 库 .so? (Vuforia)

c - JNI——带有 bool 值的 C 实现

android 应用程序在实例化 STL map 时崩溃

Android 11 - native C++ 库的 System.loadLibrary 需要 60 多秒,在 Android 10 及更低版本上运行速度非常快

android - 正确构建适用于所有 Android 架构的 FFmpeg