Reputation: 4920
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
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