【问题标题】:Calling java function from c++ using jni: Failed to find static method id使用 jni 从 c++ 调用 java 函数:无法找到静态方法 ID
【发布时间】:2015-02-13 08:45:10
【问题描述】:

我正在使用 android sdk 4.2.2 在 mac os 上创建 cocos2d-x 游戏(v. 3.4),但我也尝试了其他的。我想让 NativeHelper 类从 C++ 调用一些原生的 android 东西。我以本教程为基础:http://www.cocos2d-x.org/wiki/User_Tutorial-Integrate_AdMob 它正在工作,但我想使用带参数的 java 函数。还有错误:

02-13 09:33:20.690:W/dalvikvm(28873):虚假方法描述符:(I;)V 02-13 09:33:20.690: E/JniHelper(28873): 找不到 showBanner 的静态方法 id

这里是java实现:

public static void showBanner(int position) {
        final int _position = position;
        _appActivity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if(_appActivity != null){
                    if (!_appActivity.adView.isEnabled()){
                        _appActivity.adView.setEnabled(true);
                    }
                    if (_appActivity.adView.getVisibility() == View.INVISIBLE){
                        _appActivity.adView.setVisibility(View.VISIBLE);
                        RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                        if(_position == 0){
                            adParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                        }
                        else{
                            adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);                           
                        }
                        _appActivity.adView.setLayoutParams(adParams);
                    }
                }
            }
        });
    }

c++实现:

void NativeHelper::showBanner(int position){
    cocos2d::JniMethodInfo t;
    if (cocos2d::JniHelper::getStaticMethodInfo(t, AppActivityClassName, "showBanner", "(I;)V")){

        t.env->CallStaticVoidMethod(t.classID, t.methodID, position);

        t.env->DeleteLocalRef(t.classID);

        isBannerShowing = true;
    }
}

如果我只是从两个函数中删除位置参数(并将 (I;)V 更改为 ()V ),它就像一个魅力。我尝试了其他参数类型,例如 bool,它也不起作用。

我想我可能做错了什么,所以我找到了这个教程: http://stnguyen.com/cocos2d-x/call-java-functions-from-cpp.html

例如调用 sayHello 也不起作用:

02-13 09:33:16.955:W/dalvikvm(28873):虚假方法描述符: (Ljava/lang/String;I;)V 02-13 09:33:16.955: E/JniHelper(28873): 失败 查找 sayHello 的静态方法 id

我正在使用 ndk r9,但也尝试了 r10。 我基本上没有想法......

【问题讨论】:

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


    【解决方案1】:

    你可以直接打开编译好的.class文件,搜索方法名。 编译后的文件将是一个 hex 文件,但方法名称和参数是文本。 见Sample

    public void InitUserData(int sdk_app_id, String account_type, String 
    app_id_3rd, String identifier, String user_sig)
    
    =======>
    
    InitUserDataL(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
    

    使用javap也可以,但是打开.class文件更方便。

    【讨论】:

      【解决方案2】:

      你打错了。应该是“(I)V”,而不是“(I;)V”

      【讨论】:

      • 道德:不要编写自己的 JNI 方法签名。使用javap -s.的输出永远不会出错。
      • 哇,你成就了我的一天!我不是 JNI 专家,但为什么教程中的代码是错误的? :)
      • @Makalele 什么代码? (I;)V 没有出现在该页面上。 但是 ...不要像这样随意使用互联网垃圾。使用官方教程,
      • 例如这段代码:static String doMeAFavour(int times) //签名:“(I;)Ljava/lang/String;”。谢谢大家的回复。
      【解决方案3】:

      对我来说,double myfunction(java.lang.String astringparam) {} 需要 (Ljava/lang/String;)D。没有分号的 (Ljava/lang/String)D 不起作用。

      顺便说一句,我在命令行上使用“javap -s -classpath bin/classes/org/cocos2dx/javascript/AppActivity”来获取签名。 (感谢@EJP)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-22
        • 2012-07-04
        • 2012-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多