Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JNI—从C++; 我一直试图从C++调用java方法,但没有任何运气。这是我收到的错误:_Java_Android_C++_Crash_Java Native Interface - Fatal编程技术网

JNI—从C++; 我一直试图从C++调用java方法,但没有任何运气。这是我收到的错误:

JNI—从C++; 我一直试图从C++调用java方法,但没有任何运气。这是我收到的错误:,java,android,c++,crash,java-native-interface,Java,Android,C++,Crash,Java Native Interface,JNI错误(应用程序错误):访问了过时的本地引用0x5cb00019(索引 6在尺寸为2的表格中) 虚拟机中止 0xdeadd00d(代码=1)处的致命信号11(SIGSEGV) 下面是我在代码中所做的(java方面): 这里是C++的一面: typedef struct JniMethodInfo_ { JNIEnv * env; jclass classID; jmethodID methodID;

JNI错误(应用程序错误):访问了过时的本地引用0x5cb00019(索引 6在尺寸为2的表格中) 虚拟机中止 0xdeadd00d(代码=1)处的致命信号11(SIGSEGV)

下面是我在代码中所做的(java方面):

这里是C++的一面:

    typedef struct JniMethodInfo_
    {
        JNIEnv *    env;
        jclass      classID;
        jmethodID   methodID;
    } JniMethodInfo;

    extern "C"
    {
static jobject javaObj;

// get env and cache it
static JNIEnv* getJNIEnv(void)
{

    JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
    if (NULL == jvm) {
        LOGD("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL");
        return NULL;
    }

    JNIEnv *env = NULL;
    // get jni environment
    jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4);

    switch (ret) {
        case JNI_OK :
            // Success!
            return env;

        case JNI_EDETACHED :
            // Thread not attached

            // TODO : If calling AttachCurrentThread() on a native thread
            // must call DetachCurrentThread() in future.
            // see: http://developer.android.com/guide/practices/design/jni.html

            if (jvm->AttachCurrentThread(&env, NULL) < 0)
            {
                LOGD("Failed to get the environment using AttachCurrentThread()");
                return NULL;
            } else {
                // Success : Attached and obtained JNIEnv!
                return env;
            }

        case JNI_EVERSION :
            // Cannot recover from this error
            LOGD("JNI interface version 1.4 not supported");
        default :
            LOGD("Failed to get the environment using GetEnv()");
            return NULL;
    }
}

// get class and make it a global reference, release it at endJni().
static jclass getClassID(JNIEnv *pEnv)
{
    jclass ret = pEnv->FindClass(CLASS_NAME);
    if (! ret)
    {
        LOGD("Failed to find class of %s", CLASS_NAME);
    }

    return ret;
}
static bool getMethodInfo(JniMethodInfo &methodinfo, const char *methodName, const char *paramCode)
{
    jmethodID methodID = 0;
    JNIEnv *pEnv = 0;
    bool bRet = false;

    do 
    {
        pEnv = getJNIEnv();
        if (! pEnv)
        {
            break;
        }

        jclass classID = getClassID(pEnv);

        methodID = pEnv->GetMethodID(classID, methodName, paramCode);
        if (! methodID)
        {
            LOGD("Failed to find method id of %s", methodName);
            break;
        }

        methodinfo.classID = classID;
        methodinfo.env = pEnv;
        methodinfo.methodID = methodID;


        bRet = true;
    } while (0);

    return bRet;
}   

JNIEXPORT void JNICALL Java_org_test_games_Wrapper_initJNIBridge(JNIEnv *, jobject jobj){
    LOGD("Java_org_test_games_Wrapper_initJNIBridge()");

    javaObj = jobj;

    return;
}

void upgradeAdFreeJNI()
{      
    LOGD("upgradeAdFreeJNI");

    JniMethodInfo methodInfo;
    if (! getMethodInfo(methodInfo, "upgradeAdFree", "()V"))
    {
        LOGD("Cannot find method!");
        return;
    }

    methodInfo.env->CallVoidMethod(javaObj, methodInfo.methodID);
}


}
typedef结构JniMethodInfo_
{
JNIEnv*env;
jclass classID;
jmethodID;
}JniMethodInfo;
外部“C”
{
静态jobject-javaObj;
//获取env并缓存它
静态JNIEnv*getJNIEnv(void)
{
JavaVM*jvm=cocos2d::JniHelper::getJavaVM();
if(NULL==jvm){
LOGD(“未能获取JNIEnv.JniHelper::getJavaVM()为NULL”);
返回NULL;
}
JNIEnv*env=NULL;
//获取jni环境
jint-ret=jvm->GetEnv((void**)和env,JNI\u版本1\u 4);
开关(ret){
案例JNI_OK:
//成功!
返回环境;
案例JNI_附:
//螺纹未连接
//TODO:如果在本机线程上调用AttachCurrentThread()
//以后必须调用DetachCurrentThread()。
//见:http://developer.android.com/guide/practices/design/jni.html
如果(jvm->AttachCurrentThread(&env,NULL)<0)
{
LOGD(“使用AttachCurrentThread()获取环境失败”);
返回NULL;
}否则{
//成功:附加并获得JNINEV!
返回环境;
}
案例JNI_外翻:
//无法从此错误中恢复
LOGD(“不支持JNI接口1.4版”);
违约:
LOGD(“使用GetEnv()获取环境失败”);
返回NULL;
}
}
//获取类并使其成为全局引用,在endJni()处释放它。
静态jclass getClassID(JNIEnv*pEnv)
{
jclass ret=pEnv->FindClass(类名称);
如果(!ret)
{
LOGD(“未能找到%s的类”,类名称);
}
返回ret;
}
静态bool getMethodInfo(JniMethodInfo&methodinfo,const char*methodName,const char*paramCode)
{
jmethodID=0;
JNIEnv*pEnv=0;
布尔-布雷特=假;
做
{
pEnv=getJNIEnv();
if(!pEnv)
{
打破
}
jClassID=getClassID(pEnv);
methodID=pEnv->GetMethodID(classID、methodName、paramCode);
如果(!methodID)
{
LOGD(“未能找到%s的方法id”,方法名);
打破
}
methodinfo.classID=classID;
methodinfo.env=pEnv;
methodinfo.methodID=methodID;
bRet=真;
}而(0);
返回布雷特;
}   
JNIEXPORT void JNICALL Java_org_test_games_Wrapper_initJNIBridge(JNIEnv*,jobject jobj){
LOGD(“Java_org_test_games_Wrapper_initJNIBridge()”;
javaObj=jobj;
返回;
}
void upgradeAdFreeJNI()
{      
LOGD(“升级的adfreejni”);
JniMethodInfo方法信息;
如果(!getMethodInfo(methodInfo,“upgradeAdFree”和“()V”))
{
LOGD(“找不到方法!”);
返回;
}
methodInfo.env->CallVoidMethod(javaObj,methodInfo.methodID);
}
}
这里的任何建议都将不胜感激,因为我已经被难倒了几天,这不是世界上最容易调试的任务


谢谢

问题是指向作业对象的静态指针不再有效。您需要保护它不受任何垃圾收集器运行的影响。这可以通过使用全局引用而不是本地引用来实现。 不只是分配指针,而是创建一个globalRef

JNIEXPORT void JNICALL Java_org_test_games_Wrapper_initJNIBridge(JNIEnv *, jobject jobj)
{
    LOGD("Java_org_test_games_Wrapper_initJNIBridge()");

    javaObj = env->NewGlobalRef(env, jobj);

return;
}

但是请注意,您还必须释放globafRef

您不能像错误所说的那样简单地存储指向对象的指针。当您想要存储它时,您必须存储对对象的本地或全局引用。看

改为:

    JNIEXPORT void JNICALL Java_org_test_games_Wrapper_initJNIBridge(JNIEnv *env, jobject jobj){
        LOGD("Java_org_test_games_Wrapper_initJNIBridge()");

        javaObj = NewGlobalRef(env, jobj);

        return;
    }
    JNIEXPORT void JNICALL Java_org_test_games_Wrapper_initJNIBridge(JNIEnv *env, jobject jobj){
        LOGD("Java_org_test_games_Wrapper_initJNIBridge()");

        javaObj = NewGlobalRef(env, jobj);

        return;
    }