1

ネイティブ コードを使用した Android アプリがあります。ネイティブ メソッドの呼び出し間でオブジェクトへの参照を保持するにはどうすればよいですか?

// 1: create native object and hold it
Object obj = jni_wrapper.native_getObject();

// ... do smth

// 2: return an object back to native code
Object result = jni_wrapper.native_doSmthWithObject(obj);

そのため、コードはオブジェクトへの参照を保持し、何らかの方法でそれを見つけることが期待されます (上記の例では 1: と 2: の間)。参照を保持するために、独自のクラスと特別なインスタンス フィールド (必要な場合) を作成できます。

次の解決策 (Index オブジェクトの「ポインター」インスタンス フィールドにインスタンスへのポインターを保持するだけ) を使用しましたが、機能していないようです。

Java (Index.java):

/**
 *  CXIndex
 */
public class Index {

    private long pointer;

    public long getPointer() {
        return pointer;
    }
}

ネイティブ コード:

// index
static jclass IndexClass;
static jmethodID IndexConstructor;
static jfieldID IndexPointerField;

void bindIndex(JNIEnv *env)
{
    IndexClass = env->FindClass("name/antonsmirnov/xxx/dto/Index");
    IndexConstructor = env->GetMethodID(IndexClass, "<init>", "()V");
    IndexPointerField = env->GetFieldID(IndexClass, "pointer", "J");
}

// map CXIndex
jobject mapIndex(JNIEnv *env, CXIndex *index)
{
    if (IndexClass == NULL)
        bindIndex(env);


    jobject obj = env->NewObject(IndexClass, IndexConstructor);
    jlong jpointer = reinterpret_cast<jlong>(index);

    env->SetLongField(obj, IndexPointerField, jpointer);
    return obj;
}

// map Index -> CXIndex
CXIndex unmapIndex(JNIEnv *env, jobject jindex)
{
    if (IndexClass == NULL)
        bindIndex(env);

    jlong jpointer = env->GetLongField(jindex, IndexPointerField);
    CXIndex *ptr = reinterpret_cast<CXIndex*>(jpointer);
    return *ptr;
}

これは、特定の動作をもたらす可能性のある Android に関連しています。

4

2 に答える 2

1

関数を作成できます

jlong JNI_mypackage_myclass_createMyNativePeer() {

      return new MyNativePeer();
}

次に、Java では、返された値をクラスに保持します。

class MyWrapper {
    private long mPeer;

    public void createPeer() {
       mPeer = createMyNativePeer();
    }

   private native long createMyNativePeer();

   public void controlPeer(int param) {
            controlPeer(mPeer, param);
   }

   private native void controlPeer(long peer, int param);

}

次に、その値を制御関数に渡します。

jvoid JNI_mypackage_myclass_controlPeer(jlong peer, int someParam) {
      ((*MyNativePeer)peer)->doSomething(param);
}
于 2013-10-04T14:40:37.573 に答える