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 回表示されます。これは、ライブラリが 1 回だけロードされ、同じクラスのすべてのインスタンスによって「共有」されていることを意味します。クラスインスタンスごとに1つずつ、複数回ロードすることは可能ですか?

4

1 に答える 1

3

いいえ。Linux (Android) の共有ライブラリは、プロセスに 1 回だけ読み込まれます。これが、共有ライブラリでグローバル データを使用することはほとんどありません。そのデータは、そのプロセス全体でグローバルです。

代わりに、ライブラリは、関数の呼び出し間でデータを追跡する何らかの「状態」変数 (構造体、ポインターなど) を生成および消費する必要があります。


残念ながら、私は 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 に答える