[英]native call error in ndk
MainActivity.java
package com.example.android.testjni;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
final String TAG = "TestJni";
static {
System.loadLibrary("addjni");
native_init();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
native_setup();
Log.i(TAG, "after setup mNativeMainA=0x"+Long.toHexString(mNativeMainA));
Button btn = (Button)findViewById(R.id.btn_id);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "add from jni:"+native_add(3,21));
}
});
}
private long mNativeMainA;
private static native final void native_init();
private native final int native_add(int a, int b);
private native final void native_setup();
}
MainActivity_jni.cpp
#include <jni.h>
#include <stdint.h>I
#include <sys/types.h>
#include "MainActivity.h"
struct fields_t {
// these fields provide access from C++ to the...
jclass clazzMainA; // MainActivity class
jfieldID fidMainA; //
};
static fields_t fields;
static const char* const kClassPathName = "com/example/android/testjni/MainActivity";
static void com_example_native_init(JNIEnv *env)
{
// Get the AudioEffect class
jclass clazz = env->FindClass(kClassPathName);
if (clazz == NULL) {
LOGV("Can't find %s", kClassPathName);
return;
}
fields.clazzMainA = (jclass)env->NewGlobalRef(clazz);
fields.fidMainA = env->GetFieldID(
fields.clazzMainA,
"mNativeMainA", "J");
if (fields.fidMainA == NULL) {
LOGV("Can't find fidMainA.%s", "mNativeMainA");
return;
}
LOGV("native init over!");
}
static void com_example_native_setup(JNIEnv *env, jobject thiz)
{
MainActivity *lpMainA = new MainActivity();
LOGV("native setup!thiz=%p,lpMainA=0x%lx", thiz,(jlong)(lpMainA));
env->SetLongField(thiz, fields.fidMainA, (jlong)(lpMainA));
}
static long getlpMainA(JNIEnv *env, jobject thiz)
{
jlong lpmaina = env->GetLongField(thiz, fields.fidMainA);
return lpmaina;
}
static int com_example_native_add(JNIEnv *env, jobject thiz,jint a, jint b)
{
MainActivity *lpMainA = (MainActivity *)getlpMainA(env, thiz);
LOGV("native add!a=%d,b=%d,lpMainA=0x%lx",a,b,(jlong)lpMainA);
typedef int (*func_realadd_t)(void *thiz,int,int);
func_realadd_t func_realadd = (func_realadd_t)(*(unsigned long *)(*(unsigned long *)lpMainA));
LOGV("func_realadd=0x%lx", (jlong)func_realadd);
int ret = func_realadd(thiz,a,b); //invoke method error
//ret = lpMainA->real_add(a,b);
LOGV("ret=%d", ret);
return ret;
}
// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)com_example_native_init},
{"native_add", "(II)I", (void *)com_example_native_add},
{"native_setup", "()V", (void *)com_example_native_setup}
};
jint JNI_OnLoad(JavaVM* vm, void* reserved __unused)
{
JNIEnv* env = NULL;
jint result = -1;
jclass clazz;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGV("ERROR: GetEnv failed\n");
goto bail;
}
clazz = env->FindClass(kClassPathName);
if(clazz == NULL) {
LOGV("find class error!");
goto bail;
}
env->RegisterNatives(clazz, gMethods, stores in Java the native MainActivity objectIsizeof(gMethods)/sizeof(gMethods[0]));
result = JNI_VERSION_1_4;
bail:
return result;
}
MainActivity.cpp://这是真正的功能代码
//
// Created by android on 17-4-19.
//
#include "MainActivity.h"
MainActivity::MainActivity()
{
LOGV("in MainActivity::MainActivity");
mStatus = 100;
}
int MainActivity::real_add(int a, int b)
{
LOGV("in MainActivity virtual real_add,mStatus=%d", mStatus);
if (mStatus == 100)
return a+b;
else
return -22;
}
运行结果:
04-20 08:40:10.704 25953 25953 I TestJni+++++++: native init over!
04-20 08:40:10.756 25953 25953 I TestJni+++++++: in MainActivity::MainActivity
04-20 08:40:10.756 25953 25953 I TestJni+++++++: native setup!thiz=0x7ffc85cc04,lpMainA=0x790e6f2a30
04-20 08:40:10.756 25953 25953 I TestJni : after setup mNativeMainA=0x790e6f2a30
04-20 08:40:10.834 904 940 I ActivityManager: Displayed com.example.android.testjni/.MainActivity: +202ms
04-20 08:40:13.095 25953 25953 I TestJni+++++++: native add!a=3,b=21,lpMainA=0x790e6f2a30
04-20 08:40:13.095 25953 25953 I TestJni+++++++: func_realadd=0x7917264698
04-20 08:40:13.095 25953 25953 I TestJni+++++++: in MainActivity virtual real_add,mStatus=121
04-20 08:40:13.095 25953 25953 I TestJni+++++++: ret=-22
04-20 08:40:13.095 25953 25953 I TestJni : add from jni:-22
我的问题是为什么mStatus
是121
,它应该初始化为100.我真的很困惑。 我用谷歌搜索,但没有得到任何帮助。
谢谢
得到了解决
int ret = func_realadd(thiz,a,b); //invoke method error
改成
int ret = func_realadd(lpMainA,a,b); //it's okey!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.