Dartからネイティブライブラリの関数を呼び出せるdart:ffiの使い方を調べてみました。
Androidの端末の中にはlibz.soというライブラリが存在します。
(確認方法)
adb shell
ls /system/lib
ということは、この中にある関数をDartから呼び出せるはず?
実際にやってみた
FlutterでNew Projectして、以下のコードを適当な.dartファイルに書きます。
import 'dart:ffi';
import 'package:ffi/ffi.dart';
String zlibVersion() {
final z = DynamicLibrary.open('libz.so');
final zlibVersionPointer =
z.lookup<NativeFunction<Pointer<Utf8> Function()>>('zlibVersion');
final zlibVersion =
zlibVersionPointer.asFunction<Pointer<Utf8> Function()>();
final result = Utf8.fromUtf8(zlibVersion());
return result;
}
※dart:ffiはDartのC関数呼び出しの基本的な機能。package:ffiはdart:ffiをちょっとだけ便利に使うためのライブラリです。
そして、Flutterのどっか適当なところからzlibVersion()
を呼んでみる。
1.2.11
みたいな文字列が取得できたら成功です!(手元のPixel4XLで確認)
とりあえずこれでも良いんですけど、ライブラリの読み込みは初回のみやれば良いはずなので、毎回呼ぶべき処理と初期化処理をわけて、こんな感じのクラスにしてみる。
typedef ZlibVersionFunc = Pointer<Utf8> Function();
class Zlib {
Zlib({String libName = 'libz.so'}) {
final z = DynamicLibrary.open(libName);
final zlibVersionPointer =
z.lookup<NativeFunction<ZlibVersionFunc>>('zlibVersion');
_zlibVersionFunc = zlibVersionPointer.asFunction<ZlibVersionFunc>();
}
ZlibVersionFunc _zlibVersionFunc;
String get version {
return Utf8.fromUtf8(_zlibVersionFunc());
}
}
Zlib().version
で同じ結果が取得できたら成功です!
AndroidでJavaやKotlinからネイティブライブラリを呼び出すためには、JNIバインディングのテンプレートコードを大量に書いてCMakeの設定を書いて…とかなりめんどくさかったのですが、それに比べるとDartはかなり簡単です。C言語を書かなくてもCのライブラリが使えるのはありがたい!