2017-08-10 51 views
0

1)image_api.h定义了以下方法 - int process_image(const char * svgData,void ** mapData);如何将void **传递给来自JNI C代码的C库?

2)现在我需要调用此方法,并传递正确的价值观,以process_image是从image_api.so文件

加载 - 请告诉我在JNI C包装代码中创建无效**的情况下正确的做法?

3)

JNIEXPORT jint JNICALL Java_JNITest_process_image(JNIEnv *env, jstring svgData, jobject mapData, jint status) { 

    const char *str; 
    str = (*env)->GetStringUTFChars(env, svgData, NULL); 
    **status = process_image(str, (void**)&mapData);** 

return status; 
} 

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

我面对UnsatisfiedLinkError在调用process_image方法签名不匹配

+0

'mapData'的类型是'jobject'的。这是一个指针吗? 'process-image'想要一个指向指针的指针。你正在传递一个指向'jobject'的指针。 – lurker

+0

'Java_JNITest_process_image'看起来不像一个有效的方法引用...除非你正在运行'JNITest'包名中的所有东西。但即使如此 - 不应该像'Java_JNITest_JNITest_process_image'这样的东西(假如你的类也被命名为'JNITest')?方法声明中的类名称在哪里? – Shark

回答

1

基于更新,没有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有一个标准的数据类型这只是正确的大小。

所以,我们可以使用

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); 
} 
+0

非常感谢这样有用的解释。 –

1

在你的代码

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

其第三方库,我没有获得源代码,....我只知道,如果我可以通过[void ** mapData],那么内部c代码将初始化mapData,存储一些值,然后我必须调用另一个函数,然后我需要传递mapData ..... –

+0

你至少知道mapData是什么吗? void *是一种将任何东西作为指针传递的方法。但是,在内部,这可能是一些结构,缓冲区,数组,无论它是什么。这个其他函数需要什么参数?它是无效的**吗?我假设你有头文件。你能在那里找到什么?我知道,这是很多问题和猜测。 – mko

相关问题