跨越平台!SQLite居然在各个平台这样使用

初看这个标题你可能会不解,SQLite 本身就是一个跨平台的数据库,在这里再说跨平台有什么意义呢?

其实不然,目前我就遇到了一个项目需要使用 SQLite 数据库,而且我甚至完全不想花多套代码在不同的平台上,毕竟每个平台的包含的相关 SDK 并不一致。举个简单的例子,在 Android 上操作 SQLite,需要用到 SQLiteDatabase 这个类,用 Java 来操作;而在 iOS 上,除了需要引入 libsqlite3.tbd 外,还需要引入 sqlite3.h 这个头文件,使用 Objective-C 来操作,到了 PC 上,虽然都是以使用 sqlite3.h 为主,但是依然会有不一致的地方,比如说种类繁多的编程语言,大多都有不同的封装,API 不一致这足以让人头疼。

因此,在不同的平台上操作 SQLite,必定会使用不同的代码。当然了,除了 SQLite 之外,实现相同的功能,在不同平台上使用不同的代码也许已经是惯例,大家也习以为常。


Roll your eggs 的习以为常!作为一个懒人,当这样一个锅需要自己背的时候,自然是去找更简单的解决方案了。目标是一套代码走天下!


那么也不多废话了,直接上手写代码,这里有很多种技术可以选择,比如说 C++sqlite3.h 还是很好用的。不过我依然是折腾自己喜欢的 CodeTyphon,因为它有更让人觉得方便的封装。

很幸运的是,CodeTyphon 已经自带了 sqlite3conn 单元,直接引用之即可。关于如何查找可引用的库,可以看 CTCTyphon-IDE PkgsFPC Pkgs 这两页,你会找到你要的。

首先先制作一个简单的数据库吧,用于测试代码能否正常工作:

然后根据数据库结构声明一个结构体,后面会用于数据传递:

与这个结构等价的 C++ 的结构体是这样的:

这一瞬间我们会发现原来操作 SQLite 是如此的简单,在此我定义了一个类,用来保存一些数据:

有了这些东西后,就可以方便的玩起来了,比如说执行一个 SQL 语句:

这段代码似乎太简单了,也许我们更加希望在出错时能够给出一个原因,那么可以改一下:

好了,现在调用这个方法时,只需要额外传入一个字符串参数,就可以获取出错时的信息。

在这个体系下,要进行查询也很简单,需要额外封装两个方法:

接下来就是导出函数了,作为一个跨平台的库,它需要被其他程序调用,那么必定有导出函数,而不同的平台下,所需要的函数形态是不一样的,特别是由于 Android 使用 JNI 来调用动态库,导出函数必须符合 JNI 的规范。

下面的例子很好的说明了导出函数的方法:

唯一需要注意的是调用协定,用于 JNI 的必须设为 stdcall,而其他的均设为 cdecl

那么再下一步就是编译,直接使用 FPC 跨平台编译器即可,编译方法很简单:

此时即可以在 Mac 端生成 libsample.dylib 以及在 Linux 端生成 libsample.so

要跨平台编译的话,稍微麻烦一点,但是也比想象中简单很多:

此时即可生成一个供 Android 系统使用的,arm 架构的 libsample.so,通过更换 -P 后面的参数,也可以编译 x86,mips 等架构的 so。

完成后再看一下 iOS 的库要怎么编译。由于 iOS 已不再允许动态加载 dylib,我们必须把代码编译为静态库,也就是 .a 文件,并且静态链接到 iOS 项目内。

此时可以得到一个用于 64 位真机的 libsample.a 文件,若是要在 32 位的 iOS 和模拟器上完成兼容,还必须再另外编译两个 .a

当我们得到了 3 个不同架构的 .a 后,有些时候需要将它们合并,使用如下命令来合并之:

这样就得到了一个融合了的 .a,它可以用于各种场合。


现在一切都准备好了,看看如何使用我们做好的库吧,以上述的 dbGetSelectResultCountdbGetSelectResult 为例,分别讲述在各平台的使用方法。

Android:

iOS:

PC(以 C++ 为例):

可以看到,不论在哪个平台上,最终得到的 API 都是一致的,这样就统一了调用方式。在此基础上,要做二次封装也是非常方便。另外,由于代码耦合几乎没有,也能够很方便的对 SQLite 的底层库的逻辑进行修改,只要 API 不变,就不会影响上层的调用。


以下是一个完整的调用代码,以 iOS 端为例,其他各端均一致:

这段代码的输出为:

可以看到,调用成功,并且正确的传递了数据。在其他平台上的效果也是完全一样的。


原文发布于微信公众号 - Android群英传(android_heroes)

原文发表时间:2017-03-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端杂货铺

deno深入揭秘及未来展望

node.js之父Ryan Dahl在一个月前发起了名为deno的项目,项目的初衷是打造一个基于v8引擎的安全的TypeScript运行时,同时实现HTML5...

1881
来自专栏Linyb极客之路

缓存三大问题及解决方案

随着互联网系统发展的逐步完善,提高系统的qps,目前的绝大部分系统都增加了缓存机制从而避免请求过多的直接与数据库操作从而造成系统瓶颈,极大的提升了用户体验和系统...

1172
来自专栏申龙斌的程序人生

零基础学编程004:集成开发环境IDE

几天前介绍了《用在线编程环境快速上手》学习Python等编程语言,这种教学环境中的例子都非常简单,你不需要在自己的电脑中安装任何的软件,就可以马上动手学习Pyt...

3225
来自专栏芋道源码1024

告诉你 Redis 是一个牛逼货

Redis 是一个 Key-Value 存储系统。和 Memcached 类似,它支持存储的 value 类型相对更多,包括 string(字符串)、 list...

1290
来自专栏逆向技术

学习逆向知识之用于游戏外挂的实现.第三讲,通过游戏外挂.分析红色警戒金钱基址.以及确定基址小技巧.

                          分析红色警戒金钱基址.以及确定基址小技巧.

1171
来自专栏Linyb极客之路

分布式之redis复习精讲

博主的《分布式之消息队列复习精讲》得到了大家的好评,内心诚惶诚恐,想着再出一篇关于复习精讲的文章。但是还是要说明一下,复习精讲的文章偏面试准备,真正在开发过程中...

1653
来自专栏mini188

openfire的组件(Component)开发

在之前的文章《Openfire阶段实践总结》中提到过一种openfire的扩展模式Compoent。本文将主要探讨对这种模式的应用与开发方法。 内部与外部组件介...

2568
来自专栏领域驱动设计DDD实战进阶

领域驱动设计之聚合与聚合根

4066
来自专栏JAVA高级架构

分布式之redis复习精讲

1534
来自专栏帅小子的日常

dubbo服务的发布和调用

4935

扫码关注云+社区

领取腾讯云代金券