繁体   English   中英

从JNI调用静态void Java方法

[英]Calling a static void Java method from JNI

我的C代码无法找到我在Java中拥有的公共静态函数调用。 它设法找到没有错误的类。

我试图将结果返回给回调方法onResponse 稍后将用更复杂的内容替换“ 5”。

我在StackOverflow上也有类似的问题,但到目前为止,没有任何变化似乎有所帮助。 也许我有逻辑错误?

我的JNI(更新#2):

void cec_debug_msg(JNIEnv *env, cec_rx_message_t* msg) {
    jclass cls = (*env)->FindClass(env, "com/example/utils/CECUtils");
    if(!cls) {
        LOGE("Could not find the CEC class.");
    } else {
        jmethodID methodid = (*env)->GetStaticMethodID(env, cls, "onResponse", "(I)V");
        if(!methodid) {
            // Code always reaches this point, never finding the method
            LOGE("Could not find the callback method.");
        } else {
            LOGV("Called static void method.");
            (*env)->CallStaticVoidMethod(env, cls, methodid, 5);
        }
    }
}

此代码包含在从此函数调用的方法中:

JNIEXPORT int JNICALL Java_com_example_utils_CECUtils_startListening(JNIEnv *env, jclass cls) {

    ...

    cec_debug_msg(env, &rx_msg);

    ...

}

我的Java(更新#1):

public class CECUtils {

    static {
        System.loadLibrary("cecutils");
    }

    public static native int startListening();

    ...

    public static void onResponse(int opcode) {
        Utils.log("CEC", "From JNI!");
    }

}

签名检查:

javap -s -p CECUtils

公共静态无效onResponse(int);

签名:(I)V

解决方案:检查ProGuard!

-keep public class com.example.utils.CECUtils {
    *;
}

尝试使用GetStaticMethodID而不是GetMethodID

注意,您还需要调用CallStaticVoidMethod而不是CallVoidMethod

请参阅此处以获取更多信息: http : //journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html

请参阅方法签名http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html

jmethodID mid =(* env)-> GetMethodID(env,cls,“回调”, “(I)V” ); (I)V确定签名

这是GetMethodID的文档:

GetMethodID

jmethodID GetMethodID(JNIEnv * env,jclass clazz,const char * name, const char * sig );

返回类或接口的实例(非静态)方法的方法ID。 该方法可以在clazz的超类之一中定义,并由clazz继承。 该方法由其名称和签名确定。

GetMethodID()导致未初始化的类被初始化。

要获取构造函数的方法ID,请提供方法名称,并提供void(V)作为返回类型。

也许您可以使用javap来确定方法的签名:

使用javap生成方法签名

为了消除手工派生方法签名时的错误,可以使用javap工具打印出方法签名。 例如,通过运行:

 javap -s -p Prompt 

您可以获得以下输出:

 Compiled from Prompt.java class Prompt extends java.lang.Object /* ACC_SUPER bit set */ { private native getLine (Ljava/lang/String;)Ljava/lang/String; public static main ([Ljava/lang/String;)V <init> ()V static <clinit> ()V } 

“ -s”标志通知javap输出签名,而不是普通的Java类型。 “ -p”标志导致包含私有成员。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM