Flutter FFI在Android平台查找GetCPUs符号失败求助
解决Flutter FFI调用Go库Android平台找不到符号的问题
核心问题分析
报错undefined symbol: GetCPUs说明Android设备上加载的so库中不存在目标符号,大概率是Go库编译架构不匹配或Android打包配置错误导致的。
具体解决步骤
1. 交叉编译Go库到Android目标架构
Windows上直接编译的so是x86架构,无法在ARM架构的Android设备上正常工作,必须针对Android的目标架构交叉编译:
编译arm64-v8a架构(主流Android设备):
set GOARCH=arm64 set GOOS=android go build -buildmode=c-shared -o 你的Flutter项目路径/android/app/src/main/jniLibs/arm64-v8a/libcc.so get_cpus.go编译armeabi-v7a架构(兼容旧设备):
set GOARCH=arm set GOARM=7 set GOOS=android go build -buildmode=c-shared -o 你的Flutter项目路径/android/app/src/main/jniLibs/armeabi-v7a/libcc.so get_cpus.go
注意:把编译好的so放到
android/app/src/main/jniLibs下对应架构的子目录中,Android会自动识别并打包对应架构的库。
2. 简化Android配置(跳过不必要的CMake)
如果使用jniLibs目录存放so库,无需配置CMake,直接删除build.gradle中的externalNativeBuild块和CMakeLists.txt即可,Android构建系统会自动处理这些预编译库。
如果坚持使用CMake,需修正配置为导入预编译库:
cmake_minimum_required(VERSION 3.4.1) add_library(cc SHARED IMPORTED) set_target_properties(cc PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcc.so LINKER_LANGUAGE C )
3. 修正Dart库加载逻辑
确保Android上加载正确的库名称,同时可以优化加载方式:
int getGo() { DynamicLibrary dylib; if (Platform.isWindows) { dylib = DynamicLibrary.open("libs/cc.dll"); } else if (Platform.isAndroid) { // Android上库名为libcc.so,直接加载 dylib = DynamicLibrary.open("libcc.so"); // 或者用process()获取已加载到进程的库,更可靠 // dylib = DynamicLibrary.process(); } else { // 其他平台处理 dylib = DynamicLibrary.open("cc.so"); } final myFunc = dylib.lookupFunction<Int32 Function(), int Function()>('GetCPUs'); return myFunc(); }
4. 验证库中的符号
用Android NDK的nm工具检查编译后的so是否包含GetCPUs符号:
# 进入NDK工具目录,比如android-ndk-r25b/toolchains/llvm/prebuilt/windows-x86_64/bin ./aarch64-linux-android-nm -D 你的so路径/libcc.so | grep GetCPUs
如果输出中出现T GetCPUs,说明符号存在;如果无输出,需检查Go代码的//export GetCPUs注释是否正确,或交叉编译命令是否有误。
内容的提问来源于stack exchange,提问作者Estherius
相关产品推荐
相关产品推荐

