Slide 1

Slide 1 text

Dart Interoperability Part.1 Incheon/Songdo 1

Slide 2

Slide 2 text

박제창 (@Dreamwalker) Flutter Seoul GDG Golang Korea 2

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Computer architecture 7 Source: https://en.wikipedia.org/wiki/Computer_architecture

Slide 8

Slide 8 text

OS architecture 8 Source: https://linux-kernel-labs.github.io/refs/heads/master/lectures/arch.html

Slide 9

Slide 9 text

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.

Slide 10

Slide 10 text

Flutter Multi-Platform 10

Slide 11

Slide 11 text

ffi foreign function interface Incheon/Songdo 11

Slide 12

Slide 12 text

foreign function interface 1. JavaScript interoperability 2. C interoperability 3. ffi gen 4. JNI (gen) 12

Slide 13

Slide 13 text

foreign function interface 1. JavaScript interoperability 2. C interoperability 3. ffi gen 4. JNI (gen) 13 Part. 1

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

JavaScript interoperability w/ Dart Incheon/Songdo 16

Slide 17

Slide 17 text

JavaScript interoperability 17 https://pub.dev/packages/js

Slide 18

Slide 18 text

JavaScript interoperability 18 function adder(a, b) { return a + b; }

Slide 19

Slide 19 text

JavaScript interoperability 19 untitled // The value below is injected by flutter build, do not touch. const serviceWorkerVersion = null;

Slide 20

Slide 20 text

JavaScript interoperability 20 @JS() library adder; import 'package:js/js.dart'; @JS() external int adder(int a, int b);

Slide 21

Slide 21 text

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; }

Slide 22

Slide 22 text

JavaScript interoperability 22 print(adder(10, 20));

Slide 23

Slide 23 text

JavaScript interoperability 23 어느날 개발한 시스템이 보안의 문제로 비밀번호를 모두 암호화해야한다고 한다. 어떻게 해야할까?

Slide 24

Slide 24 text

JavaScript interoperability 24 https://github.com/brix/crypto-js

Slide 25

Slide 25 text

JavaScript interoperability 25 https://cryptojs.gitbook.io/docs/

Slide 26

Slide 26 text

JavaScript interoperability 26

Slide 27

Slide 27 text

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); }

Slide 28

Slide 28 text

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); }

Slide 29

Slide 29 text

JavaScript interoperability 29 print(CryptoJS.SHA256("devfest"));

Slide 30

Slide 30 text

JavaScript interoperability 30 print(CryptoJS.SHA256("devfest"));

Slide 31

Slide 31 text

JavaScript interoperability 31 @JS() library cryptojs; import 'package:js/js.dart'; @JS('CryptoJS.SHA256') external String jsSha256(String values);

Slide 32

Slide 32 text

C interoperability w/ Dart Incheon/Songdo 32

Slide 33

Slide 33 text

C interoperability 33 ● C언어를 활용한 함수를 Dart 언어를 통해 호출하여 사용하는 방법 ● C/C++ 라이브러리를 Dart언어로 사용하는 방법 Dart ffi main.dart Dart OS xxx.dylib or so C&C++

Slide 34

Slide 34 text

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..

Slide 35

Slide 35 text

C interoperability 35 ● hello_world.h void hello_world(); C&C++

Slide 36

Slide 36 text

C interoperability 36 ● hello_world.c #include #include "hello.h" int main() { hello_world(); return 0; } void hello_world() { printf("Hello World\n"); } C&C++

Slide 37

Slide 37 text

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" )

Slide 38

Slide 38 text

C interoperability 38 $> cmake . // cmake를 통해 빌드 파일 생성 $> make // 생성된 빌드 파일을 기반으로 빌드 진행

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

C interoperability 40 ● hello_world.dart 1. Open DynamicLibrary file 2. Lookup Functions 3. Run dart

Slide 41

Slide 41 text

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>('hello_world') .asFunction(); dart

Slide 42

Slide 42 text

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>('hello_world') .asFunction(); dart

Slide 43

Slide 43 text

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>('hello_world') .asFunction(); dart

Slide 44

Slide 44 text

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>('hello_world') .asFunction(); dart

Slide 45

Slide 45 text

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>('hello_world') .asFunction(); dart void hello_world();

Slide 46

Slide 46 text

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("hello_world"); dart

Slide 47

Slide 47 text

C interoperability 47 ● calc.c #include #include "calc.h" int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } C&C++

Slide 48

Slide 48 text

C interoperability 48 ● calc.dart final adder = dylib.lookupFunction('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);

Slide 49

Slide 49 text

C interoperability 49 ● calc.dart final adder = dylib.lookupFunction('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);

Slide 50

Slide 50 text

C interoperability 50 ● calc.dart final adder = dylib.lookupFunction('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);

Slide 51

Slide 51 text

C interoperability 51 ● calc.dart final adder = dylib.lookupFunction('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);

Slide 52

Slide 52 text

C interoperability 52 ● calc.dart final adder = dylib.lookupFunction('add'); final result = adder(40, 2); print(result); dart int add(int a, int b);

Slide 53

Slide 53 text

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'))

Slide 54

Slide 54 text

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'))

Slide 55

Slide 55 text

난이도를 조금 올려보겠습니다 55

Slide 56

Slide 56 text

Quiz 56 void main(){ int arr[] = {10, 11, 12, 13, 14}; int *p; p = arr; printf("%d \n", *(p + 2)); printf("%d \n", *arr); } 출력 결과는?

Slide 57

Slide 57 text

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);

Slide 58

Slide 58 text

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);

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

C interoperability 63 ● pointer.dart import 'package:ffi/ffi.dart'; final p = calloc(); p.value = 3; print('3 - 5 = ${subtract(p, 5)}'); calloc.free(p); dart

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

C interoperability 65 ● pointer.dart import 'package:ffi/ffi.dart'; final p = calloc(); p.value = 3; print('3 - 5 = ${subtract(p, 5)}'); calloc.free(p); dart

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

C interoperability 67

Slide 68

Slide 68 text

C interoperability 68 ● main.go package main import "C" import "fmt" //export PrintHello func PrintHello() { fmt.Print("Hello,World") } func main() { PrintHello() } go

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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 arguments) { var path = "golib/libhello.so"; ffi.DynamicLibrary dylib = ffi.DynamicLibrary.open(path); final PrintHello helloWorld = dylib .lookup>('HelloWorld') .asFunction(); helloWorld(); }

Slide 73

Slide 73 text

Summary Incheon/Songdo 73

Slide 74

Slide 74 text

Summary 74 ● Dart Interoperability ○ JavaScript Interoperability ■ package:js ○ C Interoperability ■ dart:ffi ■ package:ffi ■ go lang w/ dart

Slide 75

Slide 75 text

Thank You 75