简体   繁体   中英

Load a native library multiple times

I've made a simple native library that can store a integer and return it.

#include <string.h>
#include <jni.h>
static int a;

void Java_com_example_testnativelibs_TestClass_setA(JNIEnv* env, jobject javaThis, jint val){
    a = val;
}
jint Java_com_example_testnativelibs_TestClass_getA(JNIEnv* env, jobject javaThis) {
      return a;
}

This is the TestClass code:

public class TestClass {
    public TestClass() {
        System.loadLibrary("ndkfoo2");
    }
public native void setA(int val);
public native int getA();
}

And then the code of my MainActivity:

TestClass a = new TestClass();
TestClass b = new TestClass();
a.setA(5);
b.setA(2);
Log.i("A VALUE",""+a.getA());
Log.i("B VALUE",""+b.getA());

The value 2 is shown two times in the log, this means that the library is loaded only once and it is "shared" by all the instances of the same class. Is it possible to load it multiple times, one for each class instance?

No. Shared libraries on Linux (Android) are loaded only once into a process. This is why you should very, very rarely ever use global data in your shared libraries -- that data is global for that entire process.

Instead your libraries should produce and consume some sort of "state" variable (struct, pointer, etc.) that keeps track of data between invocations of its functions.


Unfortunately I've never worked with the JNI, so I don't know the relevant API calls to accomplish this.

In plain Linux, you might have something like:

Public header file

typedef void* PublicState;  // Don't let consumers know anything about the
                            // state that we're keeping.

PublicState MyLib_init();
void        MyLib_free(PublicState state)
int         MyLib_getVal(PublicState state);

Private C implementation file

// This is the actual "state" object we keep track of information with.
typedef struct _PrivateState {
    int a;
} PrivateState;


PublicState MyLib_init() {
    PrivateState* state = malloc( sizeof(PrivateState) );
    // check for errors

    state->a = 42;

    return (PublicState)state;
}

int MyLib_getVal(PublicState state) {
    PrivateState* ps = (PrivateState*)state;

    return ps->a;
}

void MyLib_free(PublicState state) {
    // any other cleanup
    free(state);
}

I don't even know if this is the way you're "supposed" to do it in JNI.

See Also:

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