FFI in Flutter/Dart

8e5e5bbe7d5918e3db5102d6df2ed928?s=47 done
July 16, 2019

FFI in Flutter/Dart

8e5e5bbe7d5918e3db5102d6df2ed928?s=128

done

July 16, 2019
Tweet

Transcript

  1. Flutter/Dart における FFI Flutter Meetup Tokyo #10 1

  2. 今⽇話すこと dart:ffi の実装背景と課題 2

  3. FFI ? 3

  4. Foreign function interface 今回は C 呼び出しの話 4

  5. ⾃⼰紹介 5

  6. @sensuikan1973 低レイヤの習熟度低いです が、頻繁に FFI と付き合う運 命にあるので調べました ⾃⼰紹介 6

  7. ⾃⼰紹介 7

  8. お家で作ってるモノ ⾃⼰紹介 8

  9. 9

  10. オセロには常に C が必要 ⾃⼰紹介 10

  11. ⾃⼰紹介 11

  12. 各⾔語の C 呼び出し 前置き 12

  13. 代表的なもの ⾔語 実装⽅法 Java JNI や JNA, SWIG を使う Go

    cgo を使う Python ctypes や cffi を使う Rust extern キーワードで容易に呼べる Ruby Ruby-FFI を使う Javascript WebAssembly を使う Swift そのままいけるし、カスタムも可能 前置き 13
  14. Dart は? 14

  15. Dart から C を呼ぶ⽅法 ( これまで ) 15

  16. Native Extension Dart から C を呼ぶ⽅法 ( これまで) 16

  17. Dart 側 library sample_hello; import 'dart-ext:sample_hello'; void hello() native "Hello";

    参考: dart-lang sample_extension Dart から C を呼ぶ⽅法 ( これまで) 17
  18. C++ 側 ( ⼀部省略 ) DART_EXPORT Dart_Handle sample_hello_Init(Dart_Handle parent_library) {

    if (Dart_IsError(parent_library)) return parent_library; Dart_Handle result_code = Dart_SetNativeResolver(parent_library, ResolveName, NULL); if (Dart_IsError(result_code)) return result_code; return Dart_Null(); } void hello(Dart_NativeArguments arguments) { Dart_EnterScope(); printf("Hello\n"); Dart_ExitScope(); } Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool* auto_setup_scope) { if (!Dart_IsString(name) || auto_setup_scope == NULL) return NULL; Dart_EnterScope(); const char *cname; Dart_StringToCString(name, &cname); Dart_NativeFunction result = NULL; if (strcmp(cname, "hello") == 0) result = hello; Dart_ExitScope(); return result; } 深いレベルで拡張可能 都度 ResolveName する Dart から C を呼ぶ⽅法 ( これまで) 18
  19. わかりやすく例をもう⼀個 void isEven(Dart_NativeArguments arguments) { Dart_EnterScope(); Dart_Handle arg1 = Dart_GetNativeArgument(arguments,

    0); int64_t input; if (Dart_IsError(Dart_IntegerToInt64(arg1, &input))) { Dart_ThrowException(Dart_NewStringFromCString("Error だよ")); } Dart_SetReturnValue(arguments, Dart_NewBoolean(input % 2 == 0)); Dart_ExitScope(); } 引数と返り値の型情報が静的に定義されていない Dart から C を呼ぶ⽅法 ( これまで) 19
  20. さて、 Flutter では? 20

  21. 現状、 Swift/Objective-C, Kotlin/Java を経由する必要がある Flutter から C を呼ぶ⽅法 21

  22. Flutter から C を呼ぶ⽅法 22

  23. たくさんの の思いは? Flutter から C を呼ぶ⽅法 23

  24. ① 既存ソフトをより統合しやすくして ほしい Flutter から C を呼ぶ⽅法 24

  25. ◯ ⼤量のグルーコードがつらい ◯ 低オーバーヘッドがいい Flutter から C を呼ぶ⽅法 25

  26. SQLite Realm OpenCV crypto, ssh ... libraries などが具体例として挙げられている Flutter から

    C を呼ぶ⽅法 26
  27. ② ⼤量のデータを効率よく出し⼊れし たい なお、 Dart 2.4 から TransferableTypedData が使⽤できるようにな ったので、ある程度はそれで間に合いそう

    Flutter から C を呼ぶ⽅法 27
  28. こういう要望にどう応えるか? 28

  29. 「 Native Exstention でいいんじゃないの ...? 」 Flutter/Dart における Dart->C をどう実現するか?

    29
  30. 30

  31. ⇒ Dart VM FFI Vision に理由が述べられていた Flutter/Dart における Dart->C をどう実現するか?

    31
  32. 【 理由 1 】 名前ベースの API // dart-lang/sdk/runtime/include/dart_api.h より引⽤ DART_EXPORT

    DART_WARN_UNUSED_RESULT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value); 名前解決がキャッシュされない AOT コンパイラに厳しい ( 最悪の場合を想定したり、⼿動でアノテーションを付けてまわったりしないといけない ) Flutter/Dart における Dart->C をどう実現するか? 32
  33. 【 理由 2 】 Reflective Marshaling は効率良くない void isEmailAddress(Dart_NativeArguments arguments)

    void arguments ⇒ 引数 / 返り値が静的に型付けされた上での Marshaling の⽅が 効率良い ⇒ その点は FFI が優れている Flutter における Dart->C をどう実現するか? 33
  34. そこで、 dart : ffi https://github.com/dart-lang/sdk/tree/master/sdk/lib/ffi 34

  35. Google I/O'19 でも⾔及あり dart:ffi We are working on a new

    foreign function interface. This should help you reuse existing C and C++ code, which is important for some critical stuff “ “ 35
  36. ちなみに dart:ffi we expect that moving Flutter Engine from C

    API to FFI should significantly reduce overheads associated with crossing the boundary between Dart and native code “ “ 36
  37. どう使えるのか? dart:ffi 37

  38. import "dart:ffi" as ffi; import 'dart:io' show Platform; void main()

    { final libHelloWorld = ffi.DynamicLibrary.open("./libHelloWorld.dylib"); final helloWorld = libHelloWorld.lookupFunction <ffi.Void Function(), void Function()>("helloWorld"); helloWorld(); } https://github.com/sensuikan1973/Dart_FFI_Hello_World dart:ffi 38
  39. ちなみに、先週、 Flutter stable 版に⼊った (Android のみで試験的に触れる ) dart:ffi 39

  40. どういう構成になるのか dart:ffi 参考: dart-lang/sdk/samples/ffi/sqlite/docs/sqlite-tutorial.md 40

  41. Flutter App (Imports package) Native Library dart:ffi Package API (Does

    not expose dart:ffi) Dart C / C++ App Developer Package Developer Dart VM Team Bindings Native Library Developer Package Implementation (Code which converts C++ abstractions into Dart abstractions) Bindings: final helloWorld = libHelloWorld.lookupFunction<ffi.Void Function(), void Function()> ("helloWorld"); みたいなのを定義するレイヤーのこと dart:ffi 41
  42. 課題をいくつか紹介 参考: Dart VM FFI projects, design-scketch, sqlite sample 42

  43. 1: 例外を拾えない ⇒ C レイヤーを追加実装する Flutter App (Imports package) Native

    Library dart:ffi Package API (Does not expose dart:ffi) Dart C / C++ App Developer Package Developer Dart VM Team Bindings Native Library Developer Package Implementation (Code which converts C++ abstractions into Dart abstractions) Package Developer Glue code (Code which takes care of things such as C++ exceptions) dart:ffi 43
  44. 2: CFE への追加実装 補完や静的解析を⾏うために、 CFE (Common Front-End) への追加実装が必要。 *Dart2 VM

    からは、⽣のソースから Dart を直接実⾏できず、CFE によって⽣成された Kernel Binary(dill) を与える必 要がある dart:ffi 44
  45. 3: サポート対象のプラットフォーム 待ちきれない⼈がスケジュールを聞く ⇒ 具体的なスケジュールは⽰さないけど、近い将来その状態になるか ら待っていよう dart:ffi 45

  46. 4: 変更 / 削除時の HotReload 下での挙動は ..? dart:ffi 46

  47. その他タスクの詳細は Dart VM FFI projects を参照 正直に⾔いますと、低レイヤの勉強不⾜で、 あまり理解できてないものが多い ... dart:ffi

    47
  48. 詳しい⽅は是⾮ dart:ffi に FB を送りま しょう 48

  49. ありがとうございました 49

  50. リンク⼀覧 Dart VM FFI Vision Introduction to Dart VM Design

    and implement Dart VM FFI Flutter Support integrating with C/C++ in plugin framework Native extensions for the standalone Dart VM Support for Dart Extensions dart:ffi resolve outstanding design decisions C & C++ interop using FFI sdk/lib/ffi/ Dart Native platform dart:ffi sqllite sample The Engine architecture Writing custom platform-specific code Custom Flutter Engine Embedders Language features for FFI sensuikan1973/flutter-ffi-slide sensuikan1973/Dart_FFI_Hello_World 50