简体   繁体   English

多次加载本机库

[英]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: 这是TestClass代码:

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: 然后是我的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. 值2在日志中显示两次,这意味着该库仅加载一次,并且由同一类的所有实例“共享”。 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. 不能。Linux(Android)上的共享库仅一次加载到一个进程中。 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. 不幸的是,我从未使用过JNI,因此我不知道相关的API调用来完成此操作。

In plain Linux, you might have something like: 在普通的Linux中,您可能会遇到以下情况:

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

I don't even know if this is the way you're "supposed" to do it in JNI. 我什至不知道这是否是您在JNI中“应该”执行的方式。

See Also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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