【问题标题】:How to use JNI to call JAVA method from C如何使用JNI从C调用JAVA方法
【发布时间】:2013-05-13 20:16:54
【问题描述】:

我想使用 JNI (Java Native Interface) 来调用特定的 java setter 方法,将一个 short[] 缓冲区作为参数传递给它。

Java 方法实现如下所示:

public void setPcmLeft(short[] data) { pcm_l = data; }

如何从我的 C 函数内部使用 JNI 调用此方法。

我的代码目前如下所示:

void Java_com_companyName_lame_LameActivity_lameDecode(JNIEnv *env, jobject jobj)
{
    jclass class = (*env)->GetObjectClass(env, jobj);

    if (class != NULL) {

        jmethodID setLeftDatatID = (*env)->GetMethodID(env, class, "<setPcmLeft>", "void(V)");
        if (setLeftDatatID == NULL) {
            LOGD("(Lame) No method setLeftData");
        }  
    } 
}

当我运行它时,setLeftDataIDNULL

请注意,jobj 参数是我传入的对象,其中包含 setPcmLeft 实现。

【问题讨论】:

    标签: java c java-native-interface jniwrapper


    【解决方案1】:

    在对GetMethodID()的调用中,方法名不需要尖括号,签名需要匹配Java方法。

    jmethodID setLeftDatatID = (*env)->GetMethodID(env, class, "setPcmLeft", "([S)V");
    

    一般来说,签名的格式为( arg-types ) ret-type,按照下面链接中的说明进行编码。参数是一个short[],编码为[S。对于 void,返回类型为 V

    更多信息请访问Chapter 3 of the Oracle JNI guide

    【讨论】:

    • 什么时候需要尖括号?我看到一些像这样的代码jmethodID m_mid = env -&gt; GetMethodID(m_cls,"&lt;init&gt;","()V");
    • @smwikipedia - 您需要它们的特殊名称 &lt;init&gt;GetMethodID() 支持允许引用构造函数。 “要获取构造函数的方法 ID,请提供 作为方法名称,并提供 void (V) 作为返回类型。” -- 来自 docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/… 中的 GetMethodID() 的文档。
    【解决方案2】:

    试试这个:

       jmethodID midCallBack = (*env)->GetMethodID(env, class, "setPcmLeft", "([S)V");
    

    【讨论】:

    • 您可以使用 CallVoidMethod*() 函数之一。
    • 他可能使用了没有“[S”的早期版本。
    • 抱歉,我删除了该评论,我在代码中犯了一个错误。我错过了[S。谢谢你的回答。
    • 啊,是的,我错过了参数,只是在您发布您的参数后才注意到。
    猜你喜欢
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多