簡體   English   中英

在JNI中,無法使用GetIntField獲取Java類Android中的值

[英]In JNI Cannot using GetIntField get the value in the java class Android

我嘗試在本機類字段mInt中獲取值。 此類由SimpleJNI創建。 在此示例中,我將mInt值設置為9。JNI函數添加嘗試通過使用GetIntField獲得mInt值。 它應該在add函數中返回9。 但是似乎GetIntfield在此Jobject中找不到該字段。 我如何從JNI獲得mInt? 謝謝你的評論。

這是JNI源代碼。

static jfieldID gNative;

static jint add(JNIEnv *env, jobject thiz, jint a, jint b) {
    int result = a + b;
    LOGI("%d + %d = %d", a, b, result);
    int value = env->GetIntField(thiz , gNative);

    result = value;
    return result;
}

static const char *classPathName = "com/example/android/simplejni/Native";

static JNINativeMethod methods[] = {
    {"add", "(II)I", (void*)add },
};

static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    clazz = env->FindClass(className);
    if (clazz == NULL) {
        LOGE("Native registration unable to find class '%s'", className);
        return JNI_FALSE;
    }

    gNative = env->GetFieldID(clazz, "mInt" , "I");
    if(gNative == NULL) {
        LOGE("Get mInt field id fail");
    }

    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
        LOGE("RegisterNatives failed for '%s'", className);
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

static int registerNatives(JNIEnv* env)
{
    if (!registerNativeMethods(env, classPathName,
            methods, sizeof(methods) / sizeof(methods[0]))) {
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

typedef union {
    JNIEnv* env;
    void* venv;
} UnionJNIEnvToVoid;

jint JNI_OnLoad(JavaVM* vm, void* reserved) 
{
    UnionJNIEnvToVoid uenv;
    uenv.venv = NULL;
    jint result = -1;
    JNIEnv* env = NULL;

    LOGI("JNI_OnLoad");

    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("ERROR: GetEnv failed");
        goto bail;
    }
    env = uenv.env;

    if (registerNatives(env) != JNI_TRUE) {
        LOGE("ERROR: registerNatives failed");
        goto bail;
    }

    result = JNI_VERSION_1_4;

    bail:
    return result;
}

Native類在這里。 公共函數setval用於在此類中設置mInt值。

public class Native {
    private int mInt;
    static {
        System.loadLibrary("simplejni");
    }
    public void setval(int k){
        mInt = k;
    }
    static native int add(int a, int b);
}

SimpleJNI是代碼列表,如下。

public class SimpleJNI extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        Native nv = new Native();
        nv.setval(9);
        int sum = nv.add(2, 3);
        tv.setText("2 + 3 = " + Integer.toString(sum));
        setContentView(tv);
    }

}

您在JNI中的添加功能有誤/不是原始代碼

 static jint add(JNIEnv *env, jobject thiz, jint a, jint b) { int result = a + b; LOGI("%d + %d = %d", a, b, result); int value = env->GetIntField(thiz , gNative); result = value; return result; 

}

首先,JNI函數簽名將類似於

Java_native_add(JNIEnv * env,jobject thiz,jint a,jint b)

嘗試使用javah生成函數簽名

除非您只是為了測試JNI代碼而編寫的,否則不知道add函數的意義是什么。 如果是這樣,一個較小的示例將更容易理解。 無論如何希望這會有所幫助

我已經找到了為什么JNI add函數無法從GetIntField獲取值的根本原因。 因為本地函數聲明不能​​為靜態。 它應該是

public native int add(int a, int b);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM