flutter ffi 找不到.so 文件

问题描述 投票:0回答:1

我尝试通过 flutter dart FFI 在 android 上执行 .so 文件(针对 android 的 golang 文件构建)。当我在 Windows 上对 .dll 文件执行相同操作时,一切正常。

FFI 退出并出现错误:

E/flutter (12713): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'assets/lib.so': dlopen failed: library "assets/lib.so" not found
E/flutter (12713): #0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:43)
E/flutter (12713): #1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
E/flutter (12713): #2      dylib (package:proof2/fficheck.dart:7:34)
E/flutter (12713): #3      dylib (package:proof2/fficheck.dart)
E/flutter (12713): #4      runServer (package:proof2/fficheck.dart:10:5)
E/flutter (12713): #5      runServer (package:proof2/fficheck.dart)
E/flutter (12713): #6      main (package:proof2/main.dart:11:3)
E/flutter (12713): #7      _runMain.<anonymous closure> (dart:ui/hooks.dart:301:23)
E/flutter (12713): #8      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
E/flutter (12713): #9      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

代码片段。 lib 位于 /assets/ 目录中

import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart';
import 'package:ffi/src/utf8.dart';

typedef run_server = ffi.Pointer<Utf8> Function(); // FFI fn signature
typedef RunServer = ffi.Pointer<Utf8> Function(); // Dart fn signature
final dylib = ffi.DynamicLibrary.open('assets/lib.so');

final RunServer runServer =
    dylib.lookup<ffi.NativeFunction<run_server>>('RunServer').asFunction();
android flutter dart ffi dart-ffi
1个回答
0
投票

在 Android 中,您无法像 Windows 中那样像普通文件一样访问资源,因为它是以二进制形式打包的。

要捆绑预构建的第 3 方库,您可能需要将

.so
文件添加到
android/src/main/jniLibs/[abi]
。然后你应该能够通过
DynamicLibrary.open('libfoo.so')
加载库。这已记录在here

您需要为每个 ABI 提供一个库,因此您的项目结构应该如下所示。

.
└── android/
    └── src/
        └── main/
            └── jniLibs/
                ├── arm64-v8a/
                │   └── libfoo.so
                ├── armeabi-v7a/
                │   └── libfoo.so
                ├── x86/
                │   └── libfoo.so
                └── x86_64/
                    └── libfoo.so

另外,正如 Richard Heap 提到的,您可以使用以下代码片段将

.so
从资产复制到应用程序存储作为文件。

Future<File> getFileFromAssets(String assetPath, String filename) async {
  final Directory docDir = await getApplicationDocumentsDirectory();
  final String localPath = docDir.path;
  final String targetFilePath = '$localPath/$filename';
  File targetFile = File(targetFilePath);
  final asset = await rootBundle.load(assetPath);
  final buffer = asset.buffer;
  return targetFile.writeAsBytes(
      buffer.asUint8List(asset.offsetInBytes, asset.lengthInBytes));
}
© www.soinside.com 2019 - 2024. All rights reserved.