从C+调用回Java的问题+;在GLSurcfaceView回调期间调用

从C+调用回Java的问题+;在GLSurcfaceView回调期间调用,java,android,c++,java-native-interface,Java,Android,C++,Java Native Interface,我在Android应用程序的JAR文件中创建了一个GLSURFACHEVIEW。在OnDrFrrFrand的GLSOLVEVIEW回调中,我通过JNI调用一个本地C++方法。 在这一点上,我相信我是在GLThread中,并且在该原生方法中,我试图调用回我的应用程序名称空间中的Java类,而不是名称空间 是谁打电话的。因此,我试图在这样做之前显式地附加到UI线程,但没有成功 我收到以下错误 W/dalvikvm( 4243): JNI WARNING: can't call Lcom/main/m

我在Android应用程序的JAR文件中创建了一个GLSURFACHEVIEW。在OnDrFrrFrand的GLSOLVEVIEW回调中,我通过JNI调用一个本地C++方法。 在这一点上,我相信我是在GLThread中,并且在该原生方法中,我试图调用回我的应用程序名称空间中的Java类,而不是名称空间 是谁打电话的。因此,我试图在这样做之前显式地附加到UI线程,但没有成功

我收到以下错误

W/dalvikvm( 4243): JNI WARNING: can't call Lcom/main/myapp;.updateView on instance of Lorg/myorg/myRenderer;
W/dalvikvm( 4243):              in Lorg/myorg/ImageRenderer;.renderImageFrame:()V (CallVoidMethodV)
I/dalvikvm( 4243): "GLThread 336" prio=5 tid=16 RUNNABLE
I/dalvikvm( 4243):   | group="main" sCount=0 dsCount=0 obj=0x418029f8 self=0x400988a8
I/dalvikvm( 4243):   | sysTid=4268 nice=0 sched=0/0 cgrp=apps handle=1362099424
I/dalvikvm( 4243):   | schedstat=( 0 0 0 ) utm=83 stm=71 core=1
I/dalvikvm( 4243):   at org.myorg.ImageRenderer.renderImageFrame(Native Method)
I/dalvikvm( 4243):   at org.myorg.ImageRenderer.onDrawFrame(ImageRenderer.java:93)
I/dalvikvm( 4243):   at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
I/dalvikvm( 4243):   at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
<>我的C++代码看起来像:

JavaVM * jvm;

JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame
  (JNIEnv *env, jobject jObj) {

 jvm->AttachCurrentThread(&env, 0);

        jclass javaClass = env->FindClass("com/main/myapp");
             if(javaClass == NULL){
                 LOGD("ERROR - CANNOT FIND CLASS");
             }

        jfloatArray viewArray = env->NewFloatArray(16);
        env->SetFloatArrayRegion(viewArray, 0, 16, glmatrix.data);
        jmethodID method = env->GetMethodID(javaClass, "updateView", "([F)V");
        if(method == NULL){
            LOGD("ERROR - CANNOT ACCESS METHOD");
        }

        env->CallVoidMethod(jObj, method, viewArray);
        env->DeleteLocalRef(viewArray);

jvm->DetachCurrentThread();

}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
    jvm = vm;
    return JNI_VERSION_1_2;
}
我正在尝试调用我的应用程序名称空间中的Java类,然后 未进入发出调用的命名空间

是的,这就是问题所在。您已经在类
com.main.myapp
中查找了一个methodID,但是您正在尝试在
org.myorg.ImageRenderer
的原始jobject实例上调用该methodID!如果要从另一个“名称空间”调用方法,则有几个选项:

  • 方法必须是静态的,这样就可以找到一个类,而不需要对象
  • 另一个对象必须作为参数在本机方法中传递
  • 另一个对象必须作为原始对象(声明了本机方法)的成员/获取者进行访问,然后通过JNI方法查找和调用进行访问
  • 我正在尝试调用我的应用程序名称空间中的Java类,然后 未进入发出调用的命名空间

    是的,这就是问题所在。您已经在类
    com.main.myapp
    中查找了一个methodID,但是您正在尝试在
    org.myorg.ImageRenderer
    的原始jobject实例上调用该methodID!如果要从另一个“名称空间”调用方法,则有几个选项:

  • 方法必须是静态的,这样就可以找到一个类,而不需要对象
  • 另一个对象必须作为参数在本机方法中传递
  • 另一个对象必须作为原始对象(声明了本机方法)的成员/获取者进行访问,然后通过JNI方法查找和调用进行访问

  • 您的函数是从Java调用的,因此不应调用
    AttachCurrentThread

    函数从Java接收对
    org.myorg.myRenderer
    对象的引用,其中renderImageFrame()是一个本机方法(每个本机方法都接收Java environment
    env
    作为第一个参数,其对象引用(通常表示为
    thiz
    )作为第二个参数)

    如果要为类
    com.main.myapp
    app
    对象调用Java方法updateView(),应首先获取对该对象的引用。最简单的方法是将其作为参数传递给函数,因此现在它将声明为

     JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame(JNIEnv *env, jobject thiz, jobject app);
    
    或者,如果对
    app
    的引用是
    org.myorg.myRenderer
    的一个字段,或者通过此类的某些方法返回,则可以从
    thiz
    中找到
    app
    对象


    最后,您可能是对的,从GL线程调用需要UI线程的
    updateView()
    方法不是一个好主意。您可能应该发布
    post
    ,或者发送消息,或者只需调用
    runOnUIThread()

    您的函数是从Java调用的,因此您不应该调用
    AttachCurrentThread

    函数从Java接收对
    org.myorg.myRenderer
    对象的引用,其中renderImageFrame()是一个本机方法(每个本机方法都接收Java environment
    env
    作为第一个参数,其对象引用(通常表示为
    thiz
    )作为第二个参数)

    如果要为类
    com.main.myapp
    app
    对象调用Java方法updateView(),应首先获取对该对象的引用。最简单的方法是将其作为参数传递给函数,因此现在它将声明为

     JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame(JNIEnv *env, jobject thiz, jobject app);
    
    或者,如果对
    app
    的引用是
    org.myorg.myRenderer
    的一个字段,或者通过此类的某些方法返回,则可以从
    thiz
    中找到
    app
    对象


    最后,您可能是对的,从GL线程调用需要UI线程的
    updateView()
    方法不是一个好主意。您可能应该发出
    post
    ,或者发送消息,或者只需调用
    runOnUIThread()

    警告是关于调用updateModel(),您的代码似乎正在调用updateView(),因此它们没有完全对齐。错误消息是,该方法未在您要传递的对象(“this”指针)中定义。您可以尝试用GetObjectClass(jObj)替换FindClass()然后查看GetMethodID调用是否失败。抱歉,我之前复制粘贴了错误的消息。对其进行了编辑。而且,我最初尝试使用GetObjectClass()时遇到了相同的问题,这就是我切换到FindClass()的原因。无论哪种方式,它都可以获取/找到类和方法,只是无法调用该方法。您可能希望尝试帮助您实现这一点!您正在运行checkVirtualMethod()中的测试在CheckJNI.c.中,测试检查调用方法的对象是否是该方法声明类的实例。该对象是myRenderer,但updateView方法是在myapp中声明的。警告是关于调用updateModel(),您的代码似乎在调用updateView(),因此它们没有完全对齐。错误消息是,该方法未在您要传递的对象(“this”指针)中定义。您可以尝试使用GetObjectClass(jObj)替换FindClass(),并查看GetMethodID调用是否失败。抱歉,我之前复制粘贴了错误的消息。编辑了它。而且,我最初尝试使用GetObjectClass(),并且有相同的问题,这就是为什么我切换到FindClass()。无论哪种方式,它都可以获取/找到类和方法,只是无法调用