Flutter, use DynamicLibrary.open() on prebuild GO .so library without the need to write Native Code(Java/Swift)
I think the problem might be that Dart's FFI doesn't directly support Strings. Have a look at this sample for a way to marshal strings using the separate ffi package: https://github.com/dart-lang/samples/blob/master/ffi/system-command/linux.dart
Comments
-
jalanga over 1 year
I made a GO library and build it as an .so library. Is working loading the library in Java with
System.loadLibrary()
but I can not manage it to load directly from flutter/dart usingDynamicLibrary.open()
.I want to skip the process of calling native code, and load Shared Libraries directly in flutter.
DynamicLibrary.open
is only available on dev channel v1.10.14.Documentation with examples using Cmake: https://flutter.dev/docs/development/platform-integration/c-interop
My code:
static final DynamicLibrary nativeAddLib = DynamicLibrary.open("lib-mylib.so"); final int Function (String ifName, int tunFd, String settings) addStuff = nativeAddLib.lookup<NativeFunction<Int32 Function(String, Int32, String)>>("addStuff").asFunction();
Error:
Compiler message: lib/vpn_connection/vpn_connection_bloc.dart:20:164: Error: Expected type 'NativeFunction<Int32 Function(String, Int32, String)>' to be a valid and instantiated subtype of 'NativeType'. - 'NativeFunction' is from 'dart:ffi'. - 'Int32' is from 'dart:ffi'. final int Function (String ifName, int tunFd, String settings) addStuff = nativeAddLib.lookup<NativeFunction<Int32 Function(String, Int32, String)>>("addStuff").asFunction(); ^ Exception: Errors during snapshot creation: null #0 KernelSnapshot.build (package:flutter_tools/src/build_system /targets/dart.dart:226:7) <asynchronous suspension> #1 _BuildInstance._invokeInternal (package:flutter_tools/src/build_system/build_system.dart:526:25) <asynchronous suspension> #2 _BuildInstance.invokeTarget.<anonymous closure> (package:flutter_tools/src/build_system/build_system.dart:481:35) #3 new Future.sync (dart:async/future.dart:224:31) #4 AsyncMemoizer.runOnce (package:async/src/async_memoizer.dart:43:45) #5 _BuildInstance.invokeTarget (package:flutter_tools/src/build_system/build_system.dart:481:21)
It looks like is not finding the file/function.
My gradle:
android { compileSdkVersion 28 lintOptions { disable 'InvalidPackage' } sourceSets.main { jniLibs.srcDirs += files(extraJniDirectory) } defaultConfig { applicationId "com.custom.android" minSdkVersion 21 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" ndk { abiFilters "armeabi", "x86", "armeabi-v7a", "arm64-v8a", "x86_64" } } buildTypes { release { signingConfig signingConfigs.debug ndk { if (project.hasProperty('target-platform') && project.property('target-platform') == 'android-arm64') { abiFilters 'arm64-v8a' } else { abiFilters 'armeabi-v7a' } } } } }
Update:
I created a .so file with CMake as in the flutter example, I extract it from the apk and put it in the same folder with my go build .so file, and is working, but I can't find why my first .so file is not working from flutter but, is working from android.
Update2:
DynamicLibrary.open("lib-mylib.so")
is loaded,nativeAddLib.lookup<NativeFunction<Int32 Function(String, Int32, String)>>("addStuff")
is returning a pointer, that means the function is found, but when calling.asFunction()
it breaks.By simplifying the code:
var addStuff = nativeAddLib.lookup("addStuff").asFunction();
I get the error:
Error: Expected type 'NativeType' to be a valid and instantiated subtype of 'NativeType'. - 'NativeType' is from 'dart:ffi'.
-
jalanga over 4 yearsI will give it a try, I don't think is from String support, because I tried with different methods which are accepting Int32 and not returning(void).
-
eug over 4 yearsIf you paste the code & error messages from the simpler Int32 example that might help. void is actually similar to String - one needs to use a special ffi.Void type in the native typedef.
-
eug over 4 yearsGlad that helped! I sure hope they improve the error messages soon..