2013-06-01 53 views
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; 
} 

這是識別TestClass代碼:

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,則這意味着庫僅加載一次,並且由同一類的所有實例「共享」。是否可以多次加載,每個類實例一個?

回答

2

編號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中「應該」這樣做的方式。

另請參見:

+1

我補充說,說說這幾個鏈接,太。 –