简体   繁体   中英

How to pass void ** to a C library from JNI C code?

1) image_api.h defines following method - int process_image(const char *svgData, void **mapData) ;

2) now I need to call this method and pass proper values to process_image which is loaded from image_api.so file

-- Whats the correct approach for creating instance of void** in JNI C wrapper Code ?

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

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

I am facing UnsatisfiedLinkError while invoking process_image as the method signature not matching

In your code

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

Based on the updates, without Java the code would have looked like:

void * mapData; 
int status = process_image(svgData, &mapData);
...
int result = process_MapData(mapData);

Now we want to call process_image and process_MapData from separate native Java methods:

processImage(svgData, ?);
...
int result = processMapData(?);

Note that Java does not have pointers, so we must find some way to wrap void* . Luckily, size of such pointer is 64 bits or less. Java has a standard data type long that is just the right size.

So, we can use

native static long processImage(String svgData);
native static int porocessMapData(long mapPtr);
...
long mapPtr = processImage(svgData);
...
int result = processMapData(mapPtr);

Here is the C side:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM