Android中Jni入门常见异常

在Android中如果要编写JNI。首先要在本地编写对应的native方法:代码如下:

package com.android.jni.center;

public class NewJni {
    public native String getStringFromC();
    public native void sendData(String data);
    public native void sendIntData(int data);
    public native  int getAge();
}

编写完成后,需要生成对应的头文件。生成方式如下:

1,先用javac命令生成对应的class文件:

E:\WorkSpace\AndroidJNI\app\src\main\java>javac com/android/jni/center/NewJni.java

生成对应的class文件之后,使用javah生辰对应的头文件:

E:\WorkSpace\AndroidJNI\app\src\main\java>javah com.android.jni.center.NewJni


可能出现的问题。javac后面是需要带.java名称的,javah是不需要带.java 或者.class的。

生成对应的头文件之后,将对应的.h文件添加到对应的目录下。在项目的根目录中增加jni对应的目录,然后在jni文件中,增加对应的c文件


如果不添加对应的.h文件会出现如下异常:

E:\WorkSpace\AndroidJNI\jni>ndk-build
[arm64-v8a] Compile        : JniC <= JniC.c
E:/WorkSpace/AndroidJNI/jni/JniC.c:4:9: fatal error: 'com_android_jni_center_NewJni.h' file not found
#include<com_android_jni_center_NewJni.h>

完成之后,进入到jni对应的目录。然后输入ndk-build进行编译,然后会自动生成对应的.so文件。


常见异常总结:

E:/WorkSpace/AndroidJNI/jni/JniC.c:4:9: fatal error: 'com_android_jni_center_NewJni.h' file not found
#include<com_android_jni_center_NewJni.h>
上述错误是由于生成的.h头文件,没有和.c文件放到同一个目录,将两个文件放入同一个目录,重新执行ndk-build即可


E:/WorkSpace/AndroidJNI/jni/JniC.c:28:12: error: parameter name omitted
  (JNIEnv *, jobject){
上述错误是由于 javah生成的头文件,生成的方法中,只有参数类型,没有变量名称,类似java中的 public void say(String),没有变量名称。只要增加上对应的变量名称即可。修改成类似如下:

E:/WorkSpace/AndroidJNI/jni/JniC.c:28:12: error: parameter name omitted
  (JNIEnv * env, jobject obj){

E:/WorkSpace/AndroidJNI/jni/JniC.c:34:25: error: use of undeclared identifier 'env'
      jstring jstr2 = (*env) -> NewStringUTF(env, cstr);

上述异常,是由于找不到env这个变量,确认一下是否有这个变量即可,一般这个变量都是方法参数中的,代表c环境的上下文对象


E:/WorkSpace/AndroidJNI/jni/JniC.c:35:3: warning: control reaches end of non-void function [-Wreturn-type]
  }

上述异常,是由于对应的c文件中,35行的函数,声明有一个返回值,但是一直到函数结尾也没有return返回值,说白了就是,函数你没有返回值

E:/WorkSpace/AndroidJNI/jni/JniC.c:44:10: error: unexpected type name 'jstring': expected expression
  printf(jstring);
E:/WorkSpace/AndroidJNI/jni/JniC.c:54:8: error: unexpected type name 'jint': expected expression
printf(jint);

上述异常,是由于c中调用了打印。但是打印的内容传递的不是变量 而是类型导致的,类似于java中的 System.out.print(int) 这种写法,所以你只要将jint,jstring改成对应的变量名即可

E:/WorkSpace/AndroidJNI/jni/JniC.c:44:10: error: format string is not a string literal (potentially insecure)
      [-Werror,-Wformat-security]
  printf(str);


产生上述异常的原因是由于c的printf方法使用错误导致的,应该将对应的方法修改成printf("s%",str);printf("d%",str);



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值