Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

DEVFEST 2023 Songdo - Dart Interoperability Par...

JaiChangPark
December 09, 2023

DEVFEST 2023 Songdo - Dart Interoperability Part.1 박제창

DEVFEST Songdo 2023
Dart Interoperability Part1 박제창
https://festa.io/events/4246

JaiChangPark

December 09, 2023
Tweet

More Decks by JaiChangPark

Other Decks in Programming

Transcript

  1. Flutter is an open source framework by Google for building

    beautiful, natively compiled, multi-platform applications from a single codebase. 3
  2. Flutter is an open source framework by Google for building

    beautiful, natively compiled, multi-platform applications from a single codebase. 4
  3. Flutter is an open source framework by Google for building

    beautiful, natively compiled, multi-platform applications from a single codebase. 5
  4. Flutter Multi-Platform Mobile Bring your app idea to more users

    from day one by building with Flutter on iOS and Android simultaneously, without sacrificing features, quality, or performance. Web Easily reach more users in browsers with the same experience as on mobile devices through the power of Flutter on the web. Desktop & Embedded Build high-quality desktop apps without compromising compatibility or performance. Flutter's support for custom embedders means you can create new ways to put Flutter to work on the platforms that matter to you. 6
  5. Dart’s compiler technology 9 Source: https://dart.dev/overview#platform Native platform: For apps

    targeting mobile and desktop devices, Dart includes both a Dart VM with just-in-time (JIT) compilation and an ahead-of-time (AOT) compiler for producing machine code. Web platform: For apps targeting the web, Dart can compile for development or production purposes. Its web compiler translates Dart into JavaScript.
  6. foreign function interface A foreign function interface (FFI) is a

    mechanism by which a program written in one programming language can call routines or make use of services written or compiled in another one. An FFI is often used in contexts where calls are made into binary dynamic-link library. 14
  7. Interoperability C → C interop → dart:ffi or package:ffigen Objective-C

    & Swift ⇒ dart:ffi or package:ffigen Java & Kotlin ⇒ package:jni or package:jnigen javaScript ⇒ package:js & dart2wasm Dart2wasm Dart SDK >= 2.19 Package:js >=0.6.6 15
  8. JavaScript interoperability 19 <title>untitled</title> <link rel="manifest" href="manifest.json"> <script src="example.js" defer></script>

    <script> // The value below is injected by flutter build, do not touch. const serviceWorkerVersion = null; </script> <!-- This script adds the flutter initialization JS code --> <script src="flutter.js" defer></script>
  9. JavaScript interoperability 21 @JS() library adder; import 'package:js/js.dart'; @JS() external

    int adder(int a, int b); function adder(a, b) { return a + b; }
  10. JavaScript interoperability 27 @JS() library cryptojs; import 'package:js/js.dart'; @JS('CryptoJS') class

    CryptoJS { external static String MD5(String values); external static String SHA256(String values); }
  11. JavaScript interoperability 28 @JS() library cryptojs; import 'package:js/js.dart'; @JS('CryptoJS') class

    CryptoJS { external static String MD5(String values); external static String SHA256(String values); }
  12. C interoperability 33 • C언어를 활용한 함수를 Dart 언어를 통해

    호출하여 사용하는 방법 • C/C++ 라이브러리를 Dart언어로 사용하는 방법 Dart ffi main.dart Dart OS xxx.dylib or so C&C++
  13. preparation 34 • cmake ◦ CMake is cross-platform free and

    open-source software for build automation, testing, packaging and installation of software by using a compiler-independent method. CMake is not a build system itself; it generates another system's build files • make ◦ Make is a build automation tool that builds executable programs and libraries from source code by reading files called makefiles which specify how to derive the target program. • gcc • etc..
  14. C interoperability 36 • hello_world.c #include <stdio.h> #include "hello.h" int

    main() { hello_world(); return 0; } void hello_world() { printf("Hello World\n"); } C&C++
  15. C interoperability 37 CMakeLists.txt cmake_minimum_required(VERSION 3.7 FATAL_ERROR) project(hello_world_library VERSION 1.0.0

    LANGUAGES C) add_library(hello_world_library SHARED hello_world.c hello_world.def) add_executable(hello_test hello_world.c) set_target_properties(hello_world_library PROPERTIES PUBLIC_HEADER hello_world.h VERSION ${PROJECT_VERSION} SOVERSION 1 OUTPUT_NAME "hello_world" XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Hex_Identity_ID_Goes_Here" )
  16. C interoperability 38 $> cmake . // cmake를 통해 빌드

    파일 생성 $> make // 생성된 빌드 파일을 기반으로 빌드 진행
  17. C interoperability 39 jaichang@PARKui-MacBookPro % cmake . -- The C

    compiler identification is AppleClang 15.0.0.15000040 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Configuring done (1.1s) -- Generating done (0.0s) -- Build files have been written to: /hello_world_library jaichang@PARKui-MacBookPro % make [ 25%] Building C object CMakeFiles/hello_world_library.dir/hello.c.o [ 50%] Linking C shared library libhello.dylib [ 50%] Built target hello_world_library [ 75%] Building C object CMakeFiles/hello_test.dir/hello.c.o [100%] Linking C executable hello_test [100%] Built target hello_test
  18. C interoperability 41 • hello_world.dart import 'dart:ffi'; final dylib =

    DynamicLibrary.open('$root/mylib/lib/custom.1.0.0.dylib'); final void Function() hellos = dylib .lookup<NativeFunction<Void Function()>>('hello_world') .asFunction(); dart
  19. C interoperability 42 • hello_world.dart import 'dart:ffi'; final dylib =

    DynamicLibrary.open('$root/mylib/lib/custom.1.0.0.dylib'); final void Function() hellos = dylib .lookup<NativeFunction<Void Function()>>('hello_world') .asFunction(); dart
  20. C interoperability 43 • hello_world.dart import 'dart:ffi'; final dylib =

    DynamicLibrary.open('$root/mylib/lib/custom.1.0.0.dylib'); final void Function() hellos = dylib .lookup<NativeFunction<Void Function()>>('hello_world') .asFunction(); dart
  21. C interoperability 44 • hello_world.dart import 'dart:ffi'; final dylib =

    DynamicLibrary.open('$root/mylib/lib/custom.1.0.0.dylib'); final void Function() helloWorld = dylib .lookup<NativeFunction<Void Function()>>('hello_world') .asFunction(); dart
  22. C interoperability 45 • hello_world.dart import 'dart:ffi'; final dylib =

    DynamicLibrary.open('$root/mylib/lib/custom.1.0.0.dylib'); final void Function() hellos = dylib .lookup<NativeFunction<Void Function()>>('hello_world') .asFunction(); dart void hello_world();
  23. C interoperability 46 • hello_world.dart import 'dart:ffi'; final dylib =

    DynamicLibrary.open('$root/mylib/lib/custom.1.0.0.dylib'); final helloWorld = dylib.lookupFunction<Void Function(), void Function()>("hello_world"); dart
  24. C interoperability 47 • calc.c #include <stdio.h> #include "calc.h" int

    add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } C&C++
  25. C interoperability 48 • calc.dart final adder = dylib.lookupFunction<Int32 Function(Int32,

    Int32), int Function(int, int)>('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);
  26. C interoperability 49 • calc.dart final adder = dylib.lookupFunction<Int32 Function(Int32,

    Int32), int Function(int, int)>('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);
  27. C interoperability 50 • calc.dart final adder = dylib.lookupFunction<Int32 Function(Int32,

    Int32), int Function(int, int)>('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);
  28. C interoperability 51 • calc.dart final adder = dylib.lookupFunction<Int32 Function(Int32,

    Int32), int Function(int, int)>('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);
  29. C interoperability 52 • calc.dart final adder = dylib.lookupFunction<Int32 Function(Int32,

    Int32), int Function(int, int)>('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);
  30. C interoperability 53 Unhandled exception: Invalid argument(s): Failed to load

    dynamic library (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
  31. C interoperability 54 cmake . -DCMAKE_OSX_ARCHITECTURES=arm64 Unhandled exception: Invalid argument(s):

    Failed to load dynamic library (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
  32. Quiz 56 void main(){ int arr[] = {10, 11, 12,

    13, 14}; int *p; p = arr; printf("%d \n", *(p + 2)); printf("%d \n", *arr); } 출력 결과는?
  33. C interoperability 57 int subtract(int *a, int b) { return

    *a - b; } int *multiply(int a, int b) { int *mult = (int *)malloc(sizeof(int)); *mult = a * b; return mult; } C&C++ int subtract(int *a, int b); int *multiply(int a, int b);
  34. C interoperability 58 int subtract(int *a, int b) { return

    *a - b; } int *multiply(int a, int b) { int *mult = (int *)malloc(sizeof(int)); *mult = a * b; return mult; } C&C++ int subtract(int *a, int b); int *multiply(int a, int b);
  35. C interoperability 59 • pointer.dart // C subtract function -

    int subtract(int *a, int b); typedef SubtractFunc = Int32 Function(Pointer<Int32> a, Int32 b); typedef Subtract = int Function(Pointer<Int32> a, int b); final subtractPointer = dylib.lookup<NativeFunction<SubtractFunc>>('subtract'); final subtract = subtractPointer.asFunction<Subtract>(); dart
  36. C interoperability 60 • pointer.dart // C subtract function -

    int subtract(int *a, int b); typedef SubtractFunc = Int32 Function(Pointer<Int32> a, Int32 b); typedef Subtract = int Function(Pointer<Int32> a, int b); final subtractPointer = dylib.lookup<NativeFunction<SubtractFunc>>('subtract'); final subtract = subtractPointer.asFunction<Subtract>(); dart
  37. C interoperability 61 • pointer.dart // C subtract function -

    int subtract(int *a, int b); typedef SubtractFunc = Int32 Function(Pointer<Int32> a, Int32 b); typedef Subtract = int Function(Pointer<Int32> a, int b); final subtractPointer = dylib.lookup<NativeFunction<SubtractFunc>>('subtract'); final subtract = subtractPointer.asFunction<Subtract>(); dart
  38. C interoperability 62 • pointer.dart import 'package:ffi/ffi.dart'; dart Utilities for

    working with Foreign Function Interface (FFI) code. https://pub.dev/packages/ffi
  39. C interoperability 63 • pointer.dart import 'package:ffi/ffi.dart'; final p =

    calloc<Int32>(); p.value = 3; print('3 - 5 = ${subtract(p, 5)}'); calloc.free(p); dart
  40. C interoperability 64 • pointer.dart import 'package:ffi/ffi.dart'; final p =

    calloc<Int32>(); p.value = 3; print('3 - 5 = ${subtract(p, 5)}'); calloc.free(p); dart const CallocAllocator calloc = CallocAllocator._(); final class CallocAllocator implements Allocator { const CallocAllocator._();
  41. C interoperability 65 • pointer.dart import 'package:ffi/ffi.dart'; final p =

    calloc<Int32>(); p.value = 3; print('3 - 5 = ${subtract(p, 5)}'); calloc.free(p); dart
  42. C interoperability 66 • pointer.dart import 'package:ffi/ffi.dart'; final p =

    calloc<Int32>(); p.value = 3; print('3 - 5 = ${subtract(p, 5)}'); calloc.free(p); dart
  43. C interoperability 68 • main.go package main import "C" import

    "fmt" //export PrintHello func PrintHello() { fmt.Print("Hello,World") } func main() { PrintHello() } go
  44. C interoperability 69 • main.go import "C" import "fmt" //export

    PrintHello func PrintHello() { fmt.Print("Hello,World") } func main() { PrintHello() } go go build -o libhello.so -buildmode=c-shared main.go
  45. C interoperability 70 • main.go import "C" import "fmt" //export

    PrintHello func PrintHello() { fmt.Print("Hello,World") } func main() { PrintHello() } go go build -o libhello.so -buildmode=c-shared main.go
  46. C interoperability 71 • main.go import "C" import "fmt" //export

    PrintHello func PrintHello() { fmt.Print("Hello,World") } func main() { PrintHello() } go go build -o libhello.so -buildmode=c-shared main.go
  47. C interoperability 72 • hello_world.dart dart import 'dart:ffi' as ffi;

    typedef PrintHello_func = ffi.Void Function(); typedef PrintHello = void Function(); void main(List<String> arguments) { var path = "golib/libhello.so"; ffi.DynamicLibrary dylib = ffi.DynamicLibrary.open(path); final PrintHello helloWorld = dylib .lookup<ffi.NativeFunction<PrintHello_func>>('HelloWorld') .asFunction(); helloWorld(); }
  48. Summary 74 • Dart Interoperability ◦ JavaScript Interoperability ▪ package:js

    ◦ C Interoperability ▪ dart:ffi ▪ package:ffi ▪ go lang w/ dart