SQLite在NDK中的重生
这个问题的起因是,某项目需要在 NDK 中使用 SQLite,并且这个库同时也需要在 iOS 端使用。一开始的开发均很顺利,已有文章予以总结,点击查看该文章(http://rarnu.com/index.php/2017/03/17/sqlite_cross_platform/)。
但是当程序运行到 Android N 上时,情况就不对了,整个程序直接崩溃,报的错误是 Can not load dynamic library "libsqlite.so"。保险起见,我检查了一下 /system/lib 和 /system/lib64,确保了 libsqlite.so 是存在的。那么问题就变成了,无法调用这个存在的库?
经过一番搜索,找到了问题的原因,点此查看原文(http://ericsink.com/entries/sqlite_android_n.html),具体的原因是,Android N 以后,不再允许直接调用 /system/lib 内的内容,而允许调用的库,如 liblog.so,均被移至 vendor 下,并符号链接至 /system/lib。
所以,libsqlite.so 既便存在,也无法再直接调用了。再深入讲一句,其实 libdl.so 也无法再使用了,也就是说,在 NDK 中 dlopen 和 dlsym 这类函数也已被禁用。
既然不能动态调用,那解决方案就是静态调用了,我们需要一个 libsqlite.a,并把它静态链接到目标库里。这一步很简单,下载 SQLite 源码后,将它编译成适用于 Android 的 libsqlite.a。
此时可以得到 SQLite 的源码,总共 4 个文件,写一个 Android.mk 来编译之:
同时还需要再写一个 Application.mk 来使用 STL:
执行一下 ndk-build 命令即可得到一个 libsqlite3.a
要完成静态链接,可以很简单的使用 linklib 这个宏命令,同时修改 sqlite3.inc 文件,将 external 指令后的库名称全部删去。
关于 external,详细的用法是:
关于 linklib,详细的用法是:
此处需要注意的是,我们仅针对 Andorid 平台进行入理,而其他平台上静态链接并没有意义,因此使用 Android 的定义宏将 linklib 包起来即可。这样在编译时,静态库就链接到目标文件里去了。
到了这一步,可以说是成功了一半,这个时候运行程序,还是会崩的,主要会崩的地方有以下几个:
这两个函数的调用,须注释掉,在这里并不需要使用,而且放着会引起找不到函数的运行时异常。
另一处崩溃在于 Android 老版本的兼容,在 Android M 以后,调用 NDK 时,不再检查 __aeabi_d2ulz 和 __aeabi_d2lz(虽然这两个函数具体做了什么我也不知道,但是反编译看函数体,是可以直接留空的),而老版本的 Android 会在调用 NDK 时进行导出函数检查,从而引发一个崩溃。要解决这个问题,只需要造出这两个函数即可:
这样就完成了对老版本 Android 的兼容。到了这一步,在 Android N 以上以 NDK 调用 SQLite 即告完成。
优秀人才不缺工作机会,只缺适合自己的好机会。但是他们往往没有精力从海量机会中找到最适合的那个。
100offer 会对平台上的人才和企业进行严格筛选,让「最好的人才」和「最好的公司」相遇。
相关文章
-
声音 案例 其他 随笔 知识 编者按 sqlite数据库已经成为手机端APP管理数据的第一选择,在取证工作中加强对其研究很有意义。 前不久,某地在办理一起电信诈骗案件中遇到一个技术问题。犯罪嫌疑人通过"59同城"APP与受害者交流信息。根据办案需要,需要把主账号与其他账号之间的交流信息汇总起来。由于"59同城"APP设
-
SQLite是一个被大家低估的数据库,但有些人认为它是一个不适合生产环境使用的玩具数据库。事实上,SQLite是一个非常可靠的数据库,它可以处理TB级的数据,但它没有网络层。接下来,本文将与大家共同探讨SQLite在过去一年中最新的SQL功能。 作者|MarkusWinand 译者|彼得 责编|屠敏 出品|CSDN(
-
作者|章鱼猫 来源|https://mp.weixin.qq.com/s/i2efmzL0ZiQ5NGLZ2cBwaQ大家好,我是章鱼猫。 SQLite大家应该都知道吧,SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中
-
原文:LearningPentestingforAndroidDevices 作者:AdityaGupta 转自:看雪学院(ID:ikanxue) 编译:飞龙使者 SQLite是一个开源数据库,具有许多类似于其他关系数据库(如SQL)的功能。如果你是应用程序开发人员,你可能还会注意到SQLite查询看起来或多或少像SQ
-
作者|JamesLong译者|弯月 出品|CSDN(ID:CSDNnews)最近我开发了一款名为absurd-sql的SQLite后端。在这款工具的帮助下,你无需将整个数据库加载到内存中,而且写入的数据还可以永久保存下来。在文本中,我将介绍一下这款Web存储API(主要是IndexedDB),展示如何将SQLite的性
-
新媒体管家 关键时刻,第一时间送达! SQLite介绍 SQLite一个非常流行的嵌入式数据库,它支持SQL语言,并且只利用很少的内存就有很好的性能。此外它还是开源的,任何人都可以使用它。许多开源项目((Mozilla,PHP,Python)都使用了SQLite. SQLite由以下几个组件组成:SQL编译器、内核、后
-
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的SQL数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,你不需要在系统中配置。 SQLite数据库的特点是它每一个数据库都是一个文件,当你查询表的完整信息时会得到创建表的语句,基本和mysql差不多。 SQLite语法 1. 这
-
什么是SQLite?SQLite是一个C语言实现的小型、快速、自包含、高可靠性、功能全面的SQL数据库引擎。 起因:刚好项目上有个需求,需要使用VS2019+.Netfamework4.6.1+SQLite完成数据层。 System.Data.SQLite库先尝试了官方的System.Data.SQLite包。 首先,
-
点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天14:00更新文章,每天掉亿点点头发... 源码精品专栏 原创|Java2021超神之路,很肝~ 中文详细注释的开源项目 RPC框架Dubbo源码解析 网络应用框架Netty源码解析 消息中间件RocketMQ源码解析 数据库中间件Shard
-
前言 RSQLite包支持在R中的非常方便地创建和使用sqlite数据库,sqlite是单文件数据库,不需要预先安装,可内嵌在程序代码中。RSQLite的主要数据库操作依赖于DBI包,DBI是R语言中关系型数据库的底层接口包,除了支持RSQLite,还支持RMySQL,RPostgreSQL等连接其他数据库的包。RS