NDK 调用 so 时的异常问题解决
来源:互联网 发布:苹果系统切换windows 编辑:程序博客网 时间:2024/06/18 17:53
这两天开始学习下android ndk的使用,给自己提了两个问题
1。 .so文件时怎么生成的?2。 生成了so文件之后要怎么取调用呢3。 为什么要用so文件,为什么要用java调用c/c++代码呢?
问题1:
站在巨人的肩膀上学习,大家可直接下载这位同学分享出来的项目学习和生成
https://github.com/wobiancao/NdkJniDemo
问题2:
(1)给我一个so文件,首先我需要知道这个so支持哪些方法,以下命令就可以查询
nm -D /Users/scucheri/AllMyProjects/AI_android/ndk/test_use_so/app/libs/armeabi/libNdkJniDemo.so
结果如下:
00000690 T Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getIv00000610 T Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getKeyValue000005e0 T Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getStringFormC00003004 A __bss_start U __cxa_atexit00000000 w __cxa_begin_cleanup00000000 w __cxa_call_unexpected U __cxa_finalize00000000 w __cxa_type_match00000000 w __gnu_Unwind_Find_exidx00003004 A _edata00003004 A _end U abort00001d99 R iv00001d68 R keyValue U memcpy
可以看出来,支持的JNI方法有 Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getIv,Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getKeyValue 和 Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getStringFormC
(2)查询到方法之后那怎么调用这个方法呢? 先将 libNdkJniDemo.so 文件放入到libs目录下,然后 在app的gradle文件中 加入以下配置
android{...sourceSets { main { jniLibs.srcDirs = ['libs'] } }}
这时候就如果在android studio中的项目工程jniLibs目录下出现了这个so文件,就说明已经导入成功。
这时候需要写一个java类作为JNI接口,实现java对c代码的调用,需要特别注意的是,这个JNI接口类的package,className都必须和so文件中支持的方法保持一致,否则就会报错 method can’t found error
比如Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getIv ,若需要调用它,需要新建的java类为JniUtils ,package name为 com.wobiancao.ndkjnidemondk
代码如下:
package com.wobiancao.ndkjnidemo.ndk;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.SecureRandom;import java.security.spec.AlgorithmParameterSpec;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;/** * Created by xy on 16/1/4. */public class JniUtils { public static native String getStringFormC(); public static native byte[] getKeyValue(); public static native byte[] getIv(); private static byte[]keyValue; private static byte[]iv; private static SecretKey key; private static AlgorithmParameterSpec paramSpec; private static Cipher ecipher; static { System.loadLibrary("NdkJniDemo"); //defaultConfig.ndk.moduleName keyValue = getKeyValue(); iv = getIv(); if(null != keyValue && null !=iv) { KeyGenerator kgen; try { kgen = KeyGenerator.getInstance("AES"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG","Crypto"); random.setSeed(keyValue); kgen.init(128,random); key =kgen.generateKey(); paramSpec =new IvParameterSpec(iv); ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (NoSuchProviderException e) { e.printStackTrace(); } } } }
除了JNI的package name和className一定要与so文件中的配置保持一致之外,还需要注意:
在执行 System.loadLibrary(“NdkJniDemo”); 时,这个名字不是指so文件的全名“libNdkJniDemo“,不包含前面的lib。
(3)问题3:
见博文:
http://allenfeng.com/2016/11/06/what-you-should-know-about-android-abi-and-so/
* so机制让开发者最大化利用已有的C和C++代码,达到重用的效果,利用软件世界积累了几十年的优秀代码;* so是二进制,没有解释编译的开消,用so实现的功能比纯java实现的功能要快;* so内存分配不受Dalivik/ART的单个应用限制,减少OOM;* 相对于java代码,二进制代码的反编译难度更大,一些核心代码可以考虑放在so中。
- NDK 调用 so 时的异常问题解决
- NDK so库的调用和编译
- NDK so库的调用和编译
- NDK so库的调用和编译
- NDK so库的调用和编译
- NDK中调用已有的so生成新的so
- NDK中调用已有的so生成新的so
- NDK中调用已有的so生成新的so
- NDK在自己的SO中调用第三方SO
- NDK在自己的SO中调用第三方SO
- NDK 生成 .so ,jni 调用
- 使用ndk-build编译 android调用的so库
- Ndk(jni)调用第三方的so库
- android ndk 怎样调用第三方的so库文件
- Android NDK调用json cpp so的方法
- android ndk 调用第三方so
- android ndk 调用第三方so
- Android NDK 生成、调用so文件
- JAVA,环境变量设置
- 面试算法题解—— 链表中环的入口节点
- 对前台传入的模糊查询字符串进行转义
- 【Java】阿里巴巴Java开发手册V1.2.0
- 在Android Stuido中使用Lint
- NDK 调用 so 时的异常问题解决
- 将字符串转变为大小写
- Android 调用系统的分享界面,进行文件分享
- java面试基础-Java中对Clone的理解
- Java 关于重写compareTo方法
- BZOJ 1565: [NOI2009]植物大战僵尸
- LeetCode53 Maximum Subarray
- break,continue,return的解释
- JAVA特性: 多态