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 6 monthsI 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.openis 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 3 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 3 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 3 yearsGlad that helped! I sure hope they improve the error messages soon..