Java 如何将void**从JNI C代码传递到C库?

Java 如何将void**从JNI C代码传递到C库?,java,c,java-native-interface,jnienv,Java,C,Java Native Interface,Jnienv,1) image_api.h定义了以下方法- 整型处理图像(常量字符*svgData,void**mapData) 2) 现在我需要调用这个方法并传递适当的值来处理从image_api.so文件加载的_image --在JNI C包装器代码中创建void**实例的正确方法是什么 (三) //////////// 调用process_image时,我遇到了不满意的链接错误,因为方法签名与代码中的不匹配 JNIEXPORT jint JNICALL Java_JNITest_process_ima

1) image_api.h定义了以下方法- 整型处理图像(常量字符*svgData,void**mapData)

2) 现在我需要调用这个方法并传递适当的值来处理从image_api.so文件加载的_image

--在JNI C包装器代码中创建void**实例的正确方法是什么

(三)

////////////

调用process_image时,我遇到了不满意的链接错误,因为方法签名与代码中的不匹配

JNIEXPORT jint JNICALL 
Java_JNITest_process_image(JNIEnv *env, 
    jstring svgData, 
    jobject mapData, // this is some Java object, you need to access it
                     // take a look here: 
                     // http://jnicookbook.owsiak.org/recipe-No-020/
    jint status      // you don't need that, and you can't return value
                     // like this in JNI
    ) {

    const char *str;
    str = (*env)->GetStringUTFChars(env, svgData, NULL);
    // Question is ... what exactly process_image does?
    // without any additional knowledge about process_image
    // it is hard to guess what goes here
    int status = process_image(str, &pointer_to_some_memory_region ); 
    return status;
}
在代码中

JNIEXPORT jint JNICALL 
Java_JNITest_process_image(JNIEnv *env, 
    jstring svgData, 
    jobject mapData, // this is some Java object, you need to access it
                     // take a look here: 
                     // http://jnicookbook.owsiak.org/recipe-No-020/
    jint status      // you don't need that, and you can't return value
                     // like this in JNI
    ) {

    const char *str;
    str = (*env)->GetStringUTFChars(env, svgData, NULL);
    // Question is ... what exactly process_image does?
    // without any additional knowledge about process_image
    // it is hard to guess what goes here
    int status = process_image(str, &pointer_to_some_memory_region ); 
    return status;
}

根据这些更新,如果没有Java,代码将如下所示:

void * mapData; 
int status = process_image(svgData, &mapData);
...
int result = process_MapData(mapData);
现在我们想从单独的本机Java方法调用process_image和process_MapData:

processImage(svgData, ?);
...
int result = processMapData(?);
请注意,Java没有指针,因此我们必须找到某种方法来包装
void*
。幸运的是,这种指针的大小是64位或更少。Java有一个标准的数据类型long,大小正好合适

所以,我们可以使用

native static long processImage(String svgData);
native static int porocessMapData(long mapPtr);
...
long mapPtr = processImage(svgData);
...
int result = processMapData(mapPtr);
这是C面:

JNIEXPORT jlong JNICALL Java_JNITest_processImage(JNIEnv *env, jclass clazz, jstring svgData) {

    char *str = (*env)->GetStringUTFChars(env, svgData, NULL);
    void* mapData;
    process_image(str, &mapData);
    (*env)->ReleaseStringUTFChars(env, svgData, str);
    return (jlong)mapData;
}

JNIEXPORT jint JNICALL Java_JNITest_processMapData(JNIEnv *env, jlcass clazz, jlong mapData) {
    return process_mapData((void *)mapData);
}

根据这些更新,如果没有Java,代码将如下所示:

void * mapData; 
int status = process_image(svgData, &mapData);
...
int result = process_MapData(mapData);
现在我们想从单独的本机Java方法调用process_image和process_MapData:

processImage(svgData, ?);
...
int result = processMapData(?);
请注意,Java没有指针,因此我们必须找到某种方法来包装
void*
。幸运的是,这种指针的大小是64位或更少。Java有一个标准的数据类型long,大小正好合适

所以,我们可以使用

native static long processImage(String svgData);
native static int porocessMapData(long mapPtr);
...
long mapPtr = processImage(svgData);
...
int result = processMapData(mapPtr);
这是C面:

JNIEXPORT jlong JNICALL Java_JNITest_processImage(JNIEnv *env, jclass clazz, jstring svgData) {

    char *str = (*env)->GetStringUTFChars(env, svgData, NULL);
    void* mapData;
    process_image(str, &mapData);
    (*env)->ReleaseStringUTFChars(env, svgData, str);
    return (jlong)mapData;
}

JNIEXPORT jint JNICALL Java_JNITest_processMapData(JNIEnv *env, jlcass clazz, jlong mapData) {
    return process_mapData((void *)mapData);
}

mapData
属于
jobject
类型。那是指针吗<代码>进程图像需要指向指针的指针。您正在传递一个指向
jobject
的指针
Java\u JNITest\u进程\u图像
看起来不是有效的方法引用。。。除非您正在从
JNITest
packagename运行所有内容。但即便如此——它不应该是类似于
Java\u JNITest\u JNITest\u process\u image
(前提是您的类也被命名为
JNITest
)的吗?方法声明中的类名在哪里?
mapData
的类型为
jobject
。那是指针吗<代码>进程图像需要指向指针的指针。您正在传递一个指向
jobject
的指针
Java\u JNITest\u进程\u图像
看起来不是有效的方法引用。。。除非您正在从
JNITest
packagename运行所有内容。但即便如此——它不应该是类似于
Java\u JNITest\u JNITest\u process\u image
(前提是您的类也被命名为
JNITest
)的吗?方法声明中的类名在哪里?它是第三方库,我没有访问源代码的权限。。。。我只知道如果我可以传递[void**mapData],那么c代码将在内部初始化mapData,存储一些值,然后我必须调用另一个函数,在那里我需要传递&mapData…..你至少知道什么是mapData吗?void*是一种将任何内容作为指针传递的方法。然而,在内部,这可能是某种结构、缓冲区、数组,不管它是什么。另一个函数的参数是什么?又来了吗?我假设你有头文件。你在那里能找到什么?我知道,这是一个第三方库,我无法访问源代码。。。。我只知道如果我可以传递[void**mapData],那么c代码将在内部初始化mapData,存储一些值,然后我必须调用另一个函数,在那里我需要传递&mapData…..你至少知道什么是mapData吗?void*是一种将任何内容作为指针传递的方法。然而,在内部,这可能是某种结构、缓冲区、数组,不管它是什么。另一个函数的参数是什么?又来了吗?我假设你有头文件。你在那里能找到什么?这是我这边的很多问题和猜测,我知道。非常感谢你这么有帮助的解释。非常感谢你这么有帮助的解释。