ffi是一个比一般通信更底层的机制,接近于jni或者jsi。主要用来做dart和c++的interop。
方法定义和绑定
dart call c++
官方demo是:
import 'dart:ffi'; // For FFI
import 'dart:io'; // For Platform.isX
final DynamicLibrary nativeAddLib = Platform.isAndroid
? DynamicLibrary.open("libnative_add.so")
: DynamicLibrary.process();
final int Function(int x, int y) nativeAdd =
nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add")
.asFunction();
nativeAdd(1, 2);
- DynamicLibrary#open->ffi_dynamic_library_patch#_open->Ffi_dl_open->ffi_dynamic_library#DN_Ffi_dl_open(宏定义出来的)->DN_HelperFfi_dl_open(宏)->LoadExtensionLibrary->dlopen(posix方法)
- DynamicLibrary#lookup->ffi_dynamic_library_patch#Ffi_dl_lookup->仍然是宏定义到ResolveSymbol->dlsym(posix)
- Pointer#asFunction,是通过front_end的transform进行直接inline的,其实调用的是_asFunctionInternal->ffi.cc#DN_Ffi_asFunctionInternal(宏)->call.cc#TrampolineFunction(直接使用dartvm构造出来一个新的方法,用来转调c++方法)
- 调用dart_api_impl.cc#Dart_Invoke->Instance(Closure)#Invoke->InvokeInstanceFunction->DartEntry#InvokeFunction->DartEntry#InvokeCode
- 会在kernel_to_il.cc中对ffi相关调用进行转换,直接把call变成FfiCallInstr。(这部分基本没看懂)
c++ call dart
也是在kernel_to_il.cc中,通过BuildGraphOfFfiCallback来转换的。
类型约束及传输
所有数据也都是通过kernel_to_il.cc来进行数据传递的,所有操作都是针对内存地址直接进行操作的。
数据和方法对象直接通过dartVM api分配到了老生代怼上,可以直接走gc。