Skip to content

Using @Native/@FfiNative in an FFI plugin on Android #923

Open
@virtualzeta

Description

@virtualzeta

I'm struggling with declaring and loading native libraries but something is wrong on Android.

Library load function with DynamicLibrary.open with which there are no problems.

String libraryNameOrigin = "native";
String libraryName = "lib${libraryNameOrigin}.so";
String libraryPathTest1 = "";
String libraryPathCompleteTest1 = platformPath(libraryName, path: libraryPathTest1);

print(File(libraryPathCompleteTest1).existsSync()); // true
print(DynamicLibrary.process().providesSymbol("dlopen")); // true
print(DynamicLibrary.executable().providesSymbol("dlopen")); // true

DynamicLibrary library = DynamicLibrary.open(libraryPathCompleteTest1); // handler with correct address

Library load function with dlopen native function that there are problems with.

const RTLD_LAZY = 0x00001;
const RTLD_LOCAL = 0x00000;
const RTLD_GLOBAL = 0x00100;
String libraryNameOrigin = "native";
String libraryName = "lib${libraryNameOrigin}.so";
String libraryPathTest2 = "/data/user/0/com.example.<app_name>/lib";
String libraryPathCompleteTest2 = platformPath(libraryName, path: libraryPathTest2);

print(File(libraryPathCompleteTest2).existsSync()); // true
print(DynamicLibrary.process().providesSymbol("dlopen")); // true
print(DynamicLibrary.executable().providesSymbol("dlopen")); // true
     Pointer<Void> libraryHandle = using((arena) {
       final libraryHandle = dlopen(
           platformPath(name, path: path).toNativeUtf8(allocator: arena).cast(),
           RTLD_LAZY | RTLD_GLOBAL);
       return libraryHandle;
     }); // handler with address 0x0

No errors but the handle has an empty pointer and is not usable to use symbols of the library.

Types of declarations used in different tests without success (in addition to others).

@FfiNative<Pointer<Void> Function(Pointer<Char>, Int)>("dlopen")
external Pointer<Void> dlopen(Pointer<Char> filename, int flags);
final Pointer<Void> Function(Pointer<Char>, int) dlopen =
     DynamicLibrary.process()
         .lookup<NativeFunction<Pointer<Void> Function(Pointer<Char>, Int)>>(
             "dlope")
         .asFunction();

Same thing also for function release with dlclose native function.

     print(DynamicLibrary.process().providesSymbol("dlclose")); // true
     print(DynamicLibrary.executable().providesSymbol("dlclose")); // true
     final int Function(Pointer<Void>) dlclose = DynamicLibrary.process()
         .lookup<NativeFunction<Int32 Function(Pointer<Void>)>>("dlclose")
         .asFunction();
     int result = dlclose(library.handle);
     print(result); // 0 but library (successfully loaded with DynamicLibrary.open) is not released

Types of declarations used in different tests without success (in addition to others).

@FfiNative<Int Function(Pointer<Void>)>("dlclose")
external int dlclose(Pointer<Void> handle);
final int Function(Pointer<Void>) dlclose = DynamicLibrary.process()
     .lookup<NativeFunction<Int32 Function(Pointer<Void>)>>("dlclose")
     .asFunction();

I have to be able to use the @FfiNative and external declaration, but since I couldn't I also tried with lookup noting that it doesn't change anything.

If it serves as information and if it impacts the flow, programming in C dlopen works fine in my system (after fixing it because the dlfcn.c and dlfcn.h files were missing).

So, why?

SDK: Flutter 3.7.3 • stable channel • Dart 2.19.2
Workspace: Flutter
Target platform: Android
Environment OS: Windows 10

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions