Your Site Title

Flutter dart:ffi

动态与静态链接

本地库可以有动态链接与静态链接, 一个静态库会嵌入到APP执行映像中, 随应用一起启动 静态链接调用DynamicLibrary.executableDynamicLibrary.process

动态链接库是单独文件放在应用中, 在需要时加载. 动态库是.so(ELF)分发, 每个架构一个 动态链接调用DynamicLibrary.open

C/C++注意事项

  1. dart:ffi 只能绑定C语言的符号, 所以C++需要加上 extern “C” attribute((visibility(“default”))) attribute((used))

  2. C/C++源码建议写在ios/Classes/native_add.cpp目录, 因为CocoaPods不允许源码在
    .podspec上层目录, 而gradle允许

ffigen

通过c/c++头文件生成ffi绑定文件, ffigen.yaml为配置文件

flutter pub run ffigen --config ffigen.yaml

ffigen依赖llvm的libclang.(dylib, so)库, 需要在ffigen.yaml指定llvm-path字段

* Install XCode 
* Install brew install llvm

Function

dart to native: 1. 定义native function type typedef DartCallbackType = Int32 Function(Int32 type, Pointer arg);

2. 定义dart function
int callback (int type, Pointer<Void> arg);

3. 获取Pointer<NativeFunction>
Pointer.fromFunction<DartCallbackType>(callback, 1);

fromFunction函数第二个参数需要传个exceptionalReturn, 当callback调用异常时返回, 需要传入常量.

String

dart to native: 1. import ‘package:ffi/ffi.dart’; 2. “abc”.toNativeUtf8().cast();

异步调用

如果C语言函数很耗时, 可以创建新的isolate调用C语言 如果C语言使用线程, 那么不能直接调用Dart回调, 并且需要注意内存溢出

[vm/ffi] Support asynchronous callbacks
How to use async callback between C++ and Dart with FFI?

Reference

Supported platforms
C interop using dart:ffi
Binding to native code using dart:ffi Dart/Flutter ffi (Foreig Function Interface) native callbacks eg: sqlite3_exec Dart FFI: managing natively allocated memory
Building a Flutter Computer Vision App Using Dart:ffi, OpenCV, and Tensorflow (Part 2)
Calling Native Libraries in Flutter with Dart FFI
Flutter FFI 内存管理 How to build a Flutter app with C/C++ libraries via FFI on Android and iOS including OpenCV, Libsodium, Cmocka and Eigen
dart-lang/ffigen