当前位置: 首页 > 知识库问答 >
问题:

从JNI调用静态void Java方法

陶弘业
2023-03-14

我的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-pcecutils

公共静态响应(int);

签字:(一)V

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

共有2个答案

云联
2023-03-14

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

*env)

下面是GetmetodID的文档:

GetMethodID

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

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

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

要获得构造函数的方法ID,请以方法名的形式提供,返回类型则为false(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”标志会导致包含私人成员。

赖运珧
2023-03-14

尝试使用GetStaticMethodID而不是GetMethodID

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

有关更多信息,请参见此处:http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html

 类似资料:
  • 问题内容: 是否可以从子静态方法调用超静态方法? 我的意思是,到目前为止,到目前为止,我有以下内容: 并且它可以工作,但是我想以一种通用的方式来做,就像调用super.loadState()一样,这似乎不起作用… 问题答案: 在Java中,静态方法不能被覆盖。原因在这里 得到了很好的解释 因此,它不依赖于被引用的对象。但是,它取决于引用的类型。因此,据说静态方法隐藏了另一个静态方法而不覆盖它。 例

  • 开始使用JNI从C调用静态java方法。具体来说,在获得一个jclass(使用FindClass)和一个jmethodID(使用GetStaticMethodID)之后,我继续调用一系列CallStatic*MethodA例程。事实证明,所有这些例程都将jclass作为第一个参数。我开始想为什么需要类对象:因为所有信息都是在GetStaticMethodID中提供的,所以JVM似乎不需要类对象来完

  • 这个问题相当复杂,我不知道以前是否有人问过,因为我不知道如何在搜索框中表达这个问题。 下面是代码: 静态成员将在更多静态方法中再次使用,但我需要首先将其时区设置为“UTC”。有没有方法调用<code>。setTimeZone(“UTC”)一劳永逸?或者我必须调用<code>。setTimeZone(“UTC”)在每个静态方法中?

  • 我最近对 PHP 5.4 进行了更新,但收到有关静态和非静态代码的错误。 这是错误: 这是第371行: 我希望有人能帮忙。

  • 问题内容: 我正在做作业,遇到了一些错误。在一个类中,我有此方法: 现在,我收到错误消息“无法从静态上下文中引用非静态方法…”,因此我将getPoints()设置为静态方法,并将变量也设置为静态,并且它可以正常工作。但是在另一种打印对象的方法中,它不起作用(我相信是由于static关键字)。 所以我的问题是,有没有一种方法可以在不创建第二个Class实例的情况下调用方法?这是我所拥有的一般构想代码

  • 问题内容: 我创建了一个C ++类,应该通过以下方式调用:http : //docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#wp9502。 我没有使其正常工作,所以我遵循了:http : //www.coderanch.com/t/525082/CPP/create-JVM-native-code- c