0

我制作了一个简单的本机库,可以存储一个整数并返回它。

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

这是测试类代码:

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

然后是我的 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());

值 2 在日志中显示了两次,这意味着该库仅加载一次,并且由同一类的所有实例“共享”。是否可以多次加载它,每个类实例加载一次?

4

1 回答 1

3

不会。Linux (Android) 上的共享库仅在进程中加载​​一次。这就是为什么您应该非常非常少地在共享库中使用全局数据——这些数据对于整个过程来说都是全局的。

相反,您的库应该生成和使用某种“状态”变量(结构、指针等),在调用其函数之间跟踪数据。


不幸的是我从来没有使用过 JNI,所以我不知道相关的 API 调用来完成这个。

在普通的 Linux 中,你可能会有类似的东西:

公共头文件

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

私有 C 实现文件

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

我什至不知道这是否是您“应该”在 JNI 中这样做的方式。

也可以看看:

于 2013-06-01T19:49:33.810 回答