Vektor88
Vektor88

Reputation: 4920

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?

Upvotes: 0

Views: 2451

Answers (1)

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137438

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:

Upvotes: 3

Related Questions