菜鸟跟大家一起学ndk(四)

5 篇文章 0 订阅

细心的童鞋会发现这是上一篇的代码,更细心的童鞋会发现我做了一点小小的改变.

把#include <> 改为了#include ""

这可能是所有刚接触c编程的童鞋都会问的问题,参考:

http://blog.163.com/liujie_267/blog/static/87469217201042811538377/

所以我这里不管是用#include<> 还是使用#include""都是可以的.


java直接调用c代码的方式我们基本学会了,如何在c里面调用java代码呢?



调用JNIEnv的"FindClass"和"GetMethodID"找到 你想调用的那个方法.

这里我们调用的是最简单的无返回值,无参数类型的方法.

运行,崩溃了.

因为这里我的class名称传入错了,应该是"com/javalong/ndk/lession04/MainActivity"

使用"/"而不是"."


修改后,运行代码,成功调用.


这里使用的是最简单的无参数,无返回值方法.

下面我们来讲,如果调用有返回值,有参数,该怎么调用.

下面我把java方法改为

 public String jniHandler(String tag,int i,int i2){
        Log.e("TEST","invoke java method "+tag+i+i2);
        return "SUCCESS";
    }

现在有3个参数,有1个String返回值.那么我调用方法的时候就应该这么写了

jmethodID jmethod = (*env).GetMethodID(mainCls,"jniHandler","(Ljava/lang/String;II)Ljava/lang/String;");
原先是"()V"现在是"(Ljava/lang/String;II)Ljava/lang/String;"

怎么改成了这么一大串.

下面我们来看一张图片.


因为String对对象不是基本类型,所以String对应的符号应该是Ljava/lang/String; 千万不要落了最后的";",不是我打错了

最后一定要带上";".

至于其他基本类型就简单了,比如int 就是I

所以我上面的三个参数,最后简写为了"Ljava/lang/String;II"

并且返回值也是String,所以就是上面的写法.

我这里就不再深入去分析了,大家自己多练习下就明白了.

如果直接这么写

jstring result= (jstring) (*env).CallObjectMethod(instance, jmethod, "JNI Method Param", 1, 3);

运行后会报错,因为"字符串"是c里面的字符串,必须转成jstring后传入.如下:

jstring result= (jstring) (*env).CallObjectMethod(instance, jmethod, env->NewStringUTF("JNI Method Param"), 1, 3);

至于后面的int就不需要转化了.

运行代码,成功.


接下来我想把返回值result打印在logcat上,于是

__android_log_print(ANDROID_LOG_ERROR, "TEST",env->GetStringUTFChars(result, false));

"make project"


这是什么鬼?

好像是说我参数错了.查看下api


第二个参数必须是 常量.而我传入的是变量.所以不行.

对c有了解的童鞋,都应该知道printf("%s","字符串"); 这里的方式也是一样的.

所以需要改成.

__android_log_print(ANDROID_LOG_ERROR, "TEST", "%s",result);


晕 这样子还是会崩溃吖.于是我想到jstring是java的对象,我应该转化为c里面对应的字符串.

于是

__android_log_print(ANDROID_LOG_ERROR, "TEST", "%s",env->GetStringUTFChars(result, false));
终于可以了


所以学习ndk 还是要一步一个坑慢慢踩吖.....


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值