我的C代码无法找到Java中的公共静态函数调用。它设法找到没有错误的类。
我试图将结果返回给回调方法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);
}
}
}
。 " 5"将被更复杂的事物取代。
我在StackOverflow上似乎有类似的问题,但到目前为止似乎没有任何变化。也许我有一个逻辑错误?
我的JNI(已更新#2):
JNIEXPORT int JNICALL Java_com_example_utils_CECUtils_startListening(JNIEnv *env, jclass cls) {
...
cec_debug_msg(env, &rx_msg);
...
}
此代码包含在从此函数调用的方法中:
public class CECUtils {
static {
System.loadLibrary("cecutils");
}
public static native int startListening();
...
public static void onResponse(int opcode) {
Utils.log("CEC", "From JNI!");
}
}
我的Java(更新#1):
-keep public class com.example.utils.CECUtils {
*;
}
签名检查:
javap -s -p CECUtils
public static void onResponse(int);
签名:(I)V
{{1}}
答案 0 :(得分:4)
尝试使用GetStaticMethodID
代替GetMethodID
。
注意,您还需要拨打CallStaticVoidMethod
而不是CallVoidMethod
。
有关详细信息,请参阅此处:http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html
答案 1 :(得分:2)
查看方法签名(http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html)
jmethodID mid =(* env) - > GetMethodID(env,cls," callback","(I)V" ); (I)V确定签名
以下是GetMethodID的文档:
<强>的GetMethodID 强>
jmethodID GetMethodID(JNIEnv * env,jclass clazz,const char * name, const char * sig );
返回类或实例(非静态)方法的方法ID 接口。该方法可以在其中一个clazz中定义 超类并由clazz继承。该方法由其确定 名称和签名。
GetMethodID()会导致初始化未初始化的类。
要获取构造函数的方法ID,请提供方法 name和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 }
&#34; -s&#34; flag通知javap输出签名而不是普通的Java类型。 &#34; -p&#34; flag会导致私有成员被包含在内。