Upgrade to Pro — share decks privately, control downloads, hide ads and more …

FFI in Flutter/Dart

done
July 16, 2019

FFI in Flutter/Dart

done

July 16, 2019
Tweet

Other Decks in Technology

Transcript

  1. 9

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

    cgo を使う Python ctypes や cffi を使う Rust extern キーワードで容易に呼べる Ruby Ruby-FFI を使う Javascript WebAssembly を使う Swift そのままいけるし、カスタムも可能 前置き 13
  3. Dart 側 library sample_hello; import 'dart-ext:sample_hello'; void hello() native "Hello";

    参考: dart-lang sample_extension Dart から C を呼ぶ⽅法 ( これまで) 17
  4. 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
  5. わかりやすく例をもう⼀個 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
  6. 30

  7. 【 理由 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
  8. 【 理由 2 】 Reflective Marshaling は効率良くない void isEmailAddress(Dart_NativeArguments arguments)

    void arguments ⇒ 引数 / 返り値が静的に型付けされた上での Marshaling の⽅が 効率良い ⇒ その点は FFI が優れている Flutter における Dart->C をどう実現するか? 33
  9. 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
  10. ちなみに 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
  11. 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
  12. 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
  13. 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
  14. 2: CFE への追加実装 補完や静的解析を⾏うために、 CFE (Common Front-End) への追加実装が必要。 *Dart2 VM

    からは、⽣のソースから Dart を直接実⾏できず、CFE によって⽣成された Kernel Binary(dill) を与える必 要がある dart:ffi 44
  15. リンク⼀覧 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