【问题标题】:jni native function overload signaturejni 本机函数重载签名
【发布时间】:2016-11-26 03:13:42
【问题描述】:

我在声明 JNI 原生函数时尝试使用函数重载。

Java 方法是:

public native static void methodaaa(String type, int errorCode);
public native static void methodaaa(String type, byte[] byts);

不重载,代码如下:

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa(JNIEnv* env, jobject thiz, jstring type, jint errorCode){}

这很好用。

然后我尝试添加重载:

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa(JNIEnv* env, jobject thiz, jstring type, jint errorCode){}

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa(JNIEnv* env, jobject thiz, jstring type, jbyteArray buffer){}

这给了我错误:

conflicting types for Java_com_xxx_yyy_JavaCallCpp_methodaaa

然后我做了一些研究,似乎我需要在要重载的函数的末尾添加一个“__”,并附加参数 Name mangling。

所以我尝试了:

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa__Ljava_lang_String_I(JNIEnv* env, jobject thiz, jstring type, jint errorCode){}

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa__Ljava_lang_String_B(JNIEnv* env, jobject thiz, jstring type, jbyteArray buffer){}

但还是不行,错误是:

No implementation found for native Lcom/xxx/yyy/JavaCallCpp;.methodaaa:(Ljava/lang/String;I)V

有谁知道如何用 jstring 作为参数编写 JNICALL 函数名或我在这里做错了什么?

任何建议将不胜感激,谢谢:)

更新:

我在这里找到了链接:

http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html

然后尝试修改我的代码:

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa__Ljava_lang_String_2I(JNIEnv* env, jobject thiz, jstring type, jint errorCode){}

JNIEXPORT void JNICALL Java_com_xxx_yyy_JavaCallCpp_methodaaa__Ljava_lang_String_2B(JNIEnv* env, jobject thiz, jstring type, jbyteArray buffer){}

但是,我仍然遇到同样的错误:

No implementation found for native Lcom/xxx/yyy/JavaCallCpp;.methodaaa:(Ljava/lang/String;I)V

【问题讨论】:

  • Ljava_lang_String_2B 将是 Ljava/lang/String;B。既然你有Ljava/lang/String;[B,你就想要Ljava_lang_String_2_3B
  • 请出示您的 Java 函数声明。然后我们会做什么@EJP says

标签: java android c++ java-native-interface


【解决方案1】:

不要试图自己找出 JNI 方法签名。使用javah 的输出。永远不会错。

【讨论】:

    【解决方案2】:

    https://edux.pjwstk.edu.pl/mat/268/lec/lect10/lecture10.html

    也许这会对你有所帮助

        /* DO NOT EDIT THIS FILE - it is machine generated */
        #include <jni.h>
        /* Header for class getter_number_GetNumber */
    
        #ifndef _Included_getter_number_GetNumber
        #define _Included_getter_number_GetNumber
        #ifdef __cplusplus
        extern "C" {
        #endif
        /*
         * Class:     getter_number_GetNumber
         * Method:    getNumber
         * Signature: ()I
         */
        JNIEXPORT jint JNICALL Java_getter_number_GetNumber_getNumber__
          (JNIEnv *, jobject);
    
        /*
         * Class:     getter_number_GetNumber
         * Method:    getNumber
         * Signature: (J)J
         */
        JNIEXPORT jlong JNICALL Java_getter_number_GetNumber_getNumber__J
          (JNIEnv *, jobject, jlong);
    
        /*
         * Class:     getter_number_GetNumber
         * Method:    getNumber
         * Signature: (FF)F
         */
       JNIEXPORT jfloat JNICALL Java_getter_number_GetNumber_getNumber__FF
          (JNIEnv *, jobject, jfloat, jfloat);
    
        #ifdef __cplusplus
        }
        #endif
        #endif
    

    原始类型的字段描述符显示在表格中。

    Java type   Field descriptor
    boolean Z
    byte    B
    char    C
    short   S
    int     I
    long    J
    float   F
    double  D
    

    【讨论】:

      【解决方案3】:

      此外,JNI 函数名称是 C,而不是 C++。它们不能重载。

      【讨论】:

      • 他们是C;但是 JNI 规范允许通过在 JNI 函数名称的尾部添加参数信息来“重载”(类似于,但与 C++ 名称修饰不同)。
      【解决方案4】:

      __J 在函数中添加,它对我有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多