这是一篇头一次做NDK开发,记录了踩坑,杂乱无章的错误记录,仅供参考.

待解决Android运行NDK程序无法加载库,无法找到库,缺失库文件,找不到c库,导致我的Android NDK程序直接崩溃退出,,经过一番侦查发现,通过file获知,我们使用的gcc编译,搞错了编译工具链,使用arm工具链编译,OK,这个问题解决,然后由弹出找不到libgcc_s.so.1,好嘛,C库缺失,很显然,我拷贝一个C库过去就好了

首先从之前制作好的最小根文件系统中提取出libgcc_s.so.1这个库文件,然后使用ADB,

ADB shell

将文件推入

adb push ./libgcc_s.so.1 /system/lib/

``

这里,它提示我们这是只读文件系统

A:\Users\defenion\Desktop\ARM练习\FASTBOOT>adb push ./libgcc_s.so.1 /system/lib/

failed to copy './libgcc_s.so.1' to '/system/lib//libgcc_s.so.1': Read-only file system

我们通过重新挂载解决它

1|root@android:/ # mount -o remount,rw /dev/null /system

[ 1499.316842] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)

Ok 看样子是挂载成功

然后重新将我们从linux根文件系统中提取出来的C库push进去

A:\Users\defenion\Desktop\ARM练习\FASTBOOT>adb push ./libgcc_s.so.1 /system/lib/

6792 KB/s (69371 bytes in 0.009s)

然后再次启动我们的Android APP,在Android Studio 的ADB信息中看到 错误依旧

Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]: 1295 could not load needed library 'libgcc_s.so.1' for 'libhardcontrol.so' (link_image[1936]: 1295 could not load needed library 'libc.so.6' for 'libgcc_s.so.1' (load_library[1091]: Library 'libc.so.6' not found))

注意,这句是重点,是因为libc.so.6导致我们不能加载刚才导入的libgcc_s.so.1库文件,

could not load needed library 'libc.so.6' for 'libgcc_s.so.1'

看来还需要将 libc.so.6 导入 ,显然啊 ,这是C系的库都没有包含,,,,并且shell中还有很多常用的sh命令被删除了,

待解决~ ! 搁置 20200106 20:18

目前看来最简单的解决办法是将Linux最小根文件系统中的C库全部copy进来

这个也很是诡异,之前使用eclipse从未出现过这种问题,使用Android Studio.就遇见了缺少依赖的动态链接库.暂不探究.

对比下他们的文件信息

```

他们同为ARM交叉编译工具链编译出来的

root@ubuntu:/mnt/hgfs/ubuntu# file *.so

之前使用eclipse时使用的NDK库,没有任何问题

libled.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, stripped

这次出问题的NDK库,使用Android Studio

libnative.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped

有区别,( ′◔ ‸◔`),,我们再次找到了线索

> 探究 `stripped`与`not stripped` ,以及`将Linux最小根文件系统中的C库全部copy进来`这个方法.

正常版本是通过NDK编译工具链编译出来的,出错的版本是通过GCC手动指定参数进行编译的

NDK编译工具链

`root@ubuntu:/usr/local/ndk/android-ndk-r8b# vim ndk-build`这东西是一个脚本,本质上依然是调用ARM-GCC进行的交叉编译.

### 关于`stripped`与`not stripped`

用file命令查看文件信息的时候,显示如下:

libcom_err.so.2: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped

libcrypto.so.10: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped

libcrypt.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

libdl.so.2: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

第一个最后显示的是stripped,第二个是not stripped。而且对于同样名字的动态库,带not stripped库会大很多。

参考`elf文件格式与动态链接库`博客

a.out和elf(Executable and Linking Format)。这两种格式中都有符号表(symbol table),其中包括所有的符号(程序的入口点还有变量的地址等等)。在elf格式中符号表的内容会比a.out格式的丰富的多。但是这些符号表可以用 strip工具去除,这样的话这个文件就无法让debug程序跟踪了,但是会生成比较小的可执行文件。a.out文件中的符号表可以被完全去除,但是 elf中的在加载运行时起着重要的作用,所以用strip永远不可能完全去除elf格式文件中的符号表。但是用strip命令不是完全安全的,比如对未连接的目标文件来说如果用strip去掉符号表的话,会导致连接器无法连接。

---

回过头来,我们接着尝试解决刚才提到的问题

* 尝试1

> 既然使用NDK编译工具链编译成功了,那我们也使用一下这个编译工具链,康康是否可行

参考以前的NDK笔记

需要编译的文件,在目录“ledtest\jni”中

–Android.mk(编译脚本)

–com_topeet_ledtest_led.c

–com_topeet_ledtest_led.h

•拷贝文件夹“jni”到Ubuntu系统,,,,(JNI文件夹为 调用底层驱动的接口)

进入jni目录执行 ndk-build编译

•编译完成后,在Ubuntu目录“../” -->“libs”-->“armeabi”中生成库文件“libled.so”,该文件就是安卓应用程序中需要的“.so”文件。

•将该文件拷贝到工程ledtest的“\libs\armeabi”目录下,库文件的编译就全部完成了。

注:这个NDK编译工具链是Android文件系统中自带的工具之一.

我们需要先建立Android.mk文件

在我们拷贝的jni文件中建立一个Andoird.mk文件 ,输入如下内容

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hardcontrol

LOCAL_SRC_FILES := native.c

LOCAL_LDLIBS += -llog

LOCAL_LDLIBS +=-lm

include $(BUILD_SHARED_LIBRARY)

第三行是编译出来的文件的名称`libxxxx.so`,第四行是我们源文件名称

编译,

root@ubuntu:~/yizhi/jni# ndk-build

Compile thumb : hardcontrol <= native.c

SharedLibrary : libhardcontrol.so

Install : libhardcontrol.so => libs/armeabi/libhardcontrol.so

生成在上层libs目录中,`../libs/armeabi/libhardcontrol.so`

放入我们的工程中,然后用前面的方法push到android的`system/lib`目录下,我们在测试

libhardcontrol.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped

这回这个和以前未出过依赖gcc库问题的库文件一样了都是剥离了符号表的stripped类型 测试!

在虚拟机上跑一下,不出所料,程序依旧崩溃退出.但是显然我们解决了这个问题,错误信息中没有提示找不到我们加载的库文件

报错信息:

Caused by: java.lang.NoClassDefFoundError: HardControl

Caused by: java.lang.ClassNotFoundException: HardControl

显然,我们的库文件成功的加载了,但是没有找到我们在C文件中指定注册的类.

使用其他的NDK库加载成功,可能是JAVA类和C指定的某些地方不匹配,暂定

static {

Log.d("AAA","AAAAAAAAA");

System.loadLibrary("adc");

}

使用其他的NDK测试成功,成功,成功的原因是这个C库中没有尝试使用

` cls = (*env)->FindClass(env, "HardControl");`这句代码

暂定 20200107 21:09

在自用的安卓手机,Android 7上测试 ,提示出了稍有区别的错误,但是本质上是一样的问题,都是找不到类

01-08 13:45:05.447 29811-29811/? A/DEBUG: Abort message: 'art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: JNI NewGlobalRef called with pending exception java.lang.ClassNotFoundException: Didn't find class "HardControl" on path: DexPathList[[zip file "/data/app/com.example.ratherdog.app_addons_0001_message-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.ratherdog.app_addons_0001_message-1/lib/arm, /system/fake-libs, /data/app/com.example.ratherdog.app_addons_0001_message-1/base.apk!/lib/armeabi, /system/lib, /vendor/

试了直接指定其他类也不行,加上包名,OKay,可以找到我们需要的类HardControl了

JNI注册类是这么写就OK

jclass cls = (*env)->FindClass(env, "com/thisway/hardlibrary/HardControl");

一定要指定包名 ,

接下来,继续报错

java.lang.NoSuchMethodError: no static or non-static method "Lcom/thisway/hardlibrary/HardControl;.ledCtrl(I)I"

错误的地点java

public class HardControl{

public static native int ledCtrl(int which,int status);

public static native int ledOpen();

public static native void ledClose();

//加载hardcontrol这个名字的C库,这种静态写法是加载C库的标准写法,因为static内的代码只能被执行一次,并且在类创建实例的时候最先执行

//static方法只执行一次,最先执行,适合用于加载库,

static {

try {

System.loadLibrary("hardcontrol");

} catch (Exception e) {

e.printStackTrace();

}

}

}

找不到这样的方法是把`ledCtrl(I)I`c

static const JNINativeMethod methods[] = {

{"ledOpen", "()I", (void )ledOpen},

{"ledClose", "()V", (void)ledClose},

{"ledCtrl", "(I)I", (void *)ledCtrl},

};

显然这里面写的不匹配.` {"ledCtrl", "(I)I", (void *)ledCtrl},`这里一个参数,java中两个参数

改为

{"ledCtrl", "(II)I", (void *)ledCtrl},

```

测试

在KindleFire HD 10中测试,Android4.4.4,通过,在虚拟机中测试通过,在魅蓝Note6,Andoird中测试通过,

完美解决 !

linux 交叉编译工具中没有libc和liblog库文件,NDK无法找到动态链接库;动态链接库找不到依赖的gcc库;JNI中无法找到要注册的类;and so on...相关推荐

  1. linux top交叉编译_ARM Linux交叉编译工具链的制作

    本次是在VMWare虚拟机里安装了CentOS5.2操作系统,并在上面编译自己的ARM交叉编译工具链,下面是相应的步骤: 首先下载crosstool0.43源码包(crosstool-0.43.tar ...

  2. ubuntu linux 交叉编译工具安装以方便查看

    ps该方法是正点原子的教程,相关资料可以去正点原子官方下载. 1.在linux下创建文件目录 mkdir tool 2`.H:\linux\[正点原子]阿尔法Linux开发板(A盘)-基础资料\[正点 ...

  3. arm hisiv100 linux,hisiv100交叉编译工具链安装

    hisi交叉编译工具链安装 一.         摘要: 交叉编译简单的说,就是A机器上编译生成,运行在B机器上.那么在A机器上的编译工具安装,就是本文所要描述的内容. 工欲善其事必先利其器,所以交叉 ...

  4. hisi linux nptl.tar,hisiv100交叉编译工具链安装

    hisi交叉编译工具链安装 一.         摘要: 交叉编译简单的说,就是A机器上编译生成,运行在B机器上.那么在A机器上的编译工具安装,就是本文所要描述的内容. 工欲善其事必先利其器,所以交叉 ...

  5. linux搭建交叉编译器,手把手教你一步一步搭建mips-linux-gcc-4.4.0交叉编译工具

    一.准备工作: 工作环境:宿主机:ubuntu10.04 linux-2.6.32-24-generic i686 gcc-4.4.3 目标机:mips32 软件包版本:binutils-2.19.1 ...

  6. 搭建powerpc交叉编译工具链

    参考文档:http://blog.sina.com.cn/s/blog_70dd16910100y7vj.html 安装环境:fedora-31 1.下载安装包 1.1 GCC软件包:http://f ...

  7. Linux 交叉编译简介

    Linux 交叉编译简介 主机,目标,交叉编译器 主机与目标 编译器是将源代码转换为可执行代码的程序.像所有程序一样,编译器运行在特定类型的计算机上,输出的新程序也运行在特定类型的计算机上. 运行编译 ...

  8. 使用 Android NDK 的交叉编译工具链移植 C/C++ 项目到安卓平台

    什么是 NDK? Android NDK 是一套可以让开发者在安卓应用开发中使用 C/C++ 实现特定模块的工具集,不是所有应用都需要用到,但是正确地使用可以有效提高应用运行效率和安全性. 为什么要在 ...

  9. linux 编译工具链,Linux工具链for TKStudio下载_Linux工具链for TKStudio官方下载-太平洋下载中心...

    Linux工具链for TKStudio是一款支持TKStudio IDE集成开发环境的辅助LINUX交叉编译工具链软件,交叉编译就是跨架构编译,编译出来的程序不能在本机执行(当然有例外情况).所以这 ...

最新文章

  1. 技术人生:本周改进计划
  2. 华为云携手秒拍,云+AI助力短视频加速发展
  3. 匹兹堡大学申请条件计算机科学,匹兹堡大学cs
  4. 伦敦大学金史密斯学院计算机专业,伦敦大学金史密斯学院 Goldsmiths, University of London...
  5. html 元素的属性
  6. 大学物理实验长度的测量实验报告_大学物理实验教案长度和质量的测量两篇
  7. 关于字节对齐以及内存占用
  8. iLogtail使用入门-K8S环境日志采集到SLS
  9. mGBA-0.9.2 免费开源的gba模拟器
  10. matlab匹配滤波器的仿真
  11. Java获取压缩包内文件数_java获取递归获取嵌套压缩包(zip和rar)中的所有文件
  12. jQuery获取屏幕宽度和高度
  13. Go的WaitGroup源码分析
  14. 苹果M1 Mac 如何卸载 iPhone 和 iPad 应用程序?
  15. Oracle select表要带双引号的原因
  16. GreenPlum 大数据平台--segment 失效问题恢复
  17. 一种与生活周旋的能力
  18. 考研《软件工程--面向对象和传统的方法》复习笔记
  19. layui框架入门篇
  20. 如何使用ChatGPT帮助孩子辅导作业?

热门文章

  1. FSMC知识详解,以及驱动TFTLCD原理
  2. 孔氏格物篇1--世界是递归的
  3. NDI传输机制和网络传输方法
  4. 两个瓶子水怎样一样多_幼儿园大班科学领域《水一样多》公开课教案
  5. DIY便携式肖像绘图机
  6. 二手书直卖 代码分享
  7. C#开发BIMFACE系列9 服务端API之获取应用支持的文件类型
  8. vlc音视频开发(三)桌面动态壁纸
  9. 武汉理工转专业计算机笔试,计算机学院武汉理工大学2009年各学院转专业工作实施细则...
  10. ElasticSearch 安装教程