Flutter Dart FFI加载Android平台.so文件失败问题求助
Flutter Android FFI加载Go编译的.so文件失败解决方案
核心问题原因
Android系统的动态链接器无法直接访问assets目录下的文件,必须将.so文件复制到应用可访问的私有目录,或者放在系统标准的jniLibs目录下才能被正确加载。
解决方案一:使用jniLibs目录(推荐)
这是Android加载本地库的标准方式,步骤如下:
- 在
android/app/src/main/下创建jniLibs目录,按CPU架构创建子目录:arm64-v8a、armeabi-v7a、x86_64等。 - 将对应架构的Go编译生成的.so文件放入对应子目录。
- Go编译命令示例(arm64-v8a架构):
GOOS=android GOARCH=arm64 go build -buildmode=c-shared -o android/app/src/main/jniLibs/arm64-v8a/lib.so
- Go编译命令示例(arm64-v8a架构):
- Dart代码中直接加载库:
系统会自动根据设备架构匹配加载对应库文件。final dylib = ffi.DynamicLibrary.open('lib.so');
解决方案二:从assets复制到私有目录后加载
如果必须将.so放在assets目录,需先复制到应用私有目录再加载:
- 确保pubspec.yaml中正确配置assets:
flutter: assets: - assets/lib.so - 修改Dart代码,完成文件复制与加载:
import 'dart:ffi' as ffi; import 'dart:io'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:ffi/ffi.dart'; typedef run_server = ffi.Pointer<Utf8> Function(); typedef RunServer = ffi.Pointer<Utf8> Function(); Future<ffi.DynamicLibrary> loadLibrary() async { // 获取应用私有文档目录 final appDir = await getApplicationDocumentsDirectory(); final libPath = '${appDir.path}/lib.so'; final libFile = File(libPath); // 文件不存在则从assets复制 if (!await libFile.exists()) { final assetBytes = await rootBundle.load('assets/lib.so'); await libFile.writeAsBytes( assetBytes.buffer.asUint8List( assetBytes.offsetInBytes, assetBytes.lengthInBytes, ), ); } return ffi.DynamicLibrary.open(libPath); } // 应用初始化时异步加载库 void main() async { WidgetsFlutterBinding.ensureInitialized(); final dylib = await loadLibrary(); final RunServer runServer = dylib.lookup<ffi.NativeFunction<run_server>>('RunServer').asFunction(); // 调用runServer逻辑... }
额外注意事项
- Go编译.so时必须指定正确的Android目标架构,否则会出现架构不兼容错误。
- 禁止直接使用
assets/lib.so路径调用DynamicLibrary.open,该方式在Android平台不被支持。
内容的提问来源于stack exchange,提问作者Vyacheslav1557
相关产品推荐
相关产品推荐

