You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Dart执行文件目录 无需用户传参访问pub包内资源

可行实现方案

下面分不同场景给出可直接落地的实现方案:

场景1:发布到pub.dev的纯Dart CLI包(非Flutter)

依托Dart生态标准配置文件即可实现路径自动查找,不需要用户传入任何参数:

  • 使用Dart官方维护的package_config包读取项目配置:所有执行过pub get的Dart/Flutter项目都会在根目录生成.dart_tool/package_config.json文件,里面记录了所有依赖包的本地存储绝对路径。
    示例实现代码:
import 'package:package_config/package_config.dart';
import 'dart:io';

Future<String> getPackageDynamicLibPath() async {
  // 自动查找当前项目的package配置
  final packageConfig = await findPackageConfig(Directory.current);
  if (packageConfig == null) {
    throw StateError('未找到package配置,请先执行pub get');
  }
  // 替换成你自己的Dart包名
  final myPackage = packageConfig.packages.firstWhere((pkg) => pkg.name == 'your_package_name');
  // 拼接你包内动态库的相对路径,比如你把动态库放在包根目录的lib/dylib/下
  final dylibDir = '${myPackage.root.toFilePath()}lib/dylib/';
  // 根据当前平台返回对应动态库的完整路径
  if (Platform.isWindows) {
    return '${dylibDir}your_lib.dll';
  } else if (Platform.isMacOS) {
    return '${dylibDir}libyour_lib.dylib';
  } else if (Platform.isLinux) {
    return '${dylibDir}libyour_lib.so';
  }
  throw UnsupportedError('当前平台不支持');
}

该方案适配所有桌面端Dart运行环境,只要依赖你包的项目执行过pub get即可正常运行,不需要用户做额外配置。

场景2:AOT编译后单独分发的二进制文件

如果你的包最终会被编译为独立的exe/elf/macho二进制文件分发,没有package_config.json可用,使用动态库内置方案:

  • 编译前将动态库读为字节数组硬编码到Dart代码中,运行时将字节写入系统临时目录再加载,完全不依赖外部路径:
    示例实现代码:
import 'dart:io';
import 'dart:typed_data';
import 'dart:ffi';

// 你可以提前写个脚本把动态库文件转换成Uint8List常量代码,编译时直接嵌入到二进制中
// 以下为不同平台的动态库字节常量示例
const _windowsDylibBytes = Uint8List.fromList([/* 你的dll文件字节数组 */]);
const _macosDylibBytes = Uint8List.fromList([/* 你的dylib文件字节数组 */]);
const _linuxDylibBytes = Uint8List.fromList([/* 你的so文件字节数组 */]);

Future<DynamicLibrary> loadDynamicLib() async {
  // 选择对应平台的动态库字节
  final dylibBytes = Platform.isWindows 
    ? _windowsDylibBytes 
    : Platform.isMacOS 
      ? _macosDylibBytes 
      : _linuxDylibBytes;
  // 写入系统临时目录
  final tempDir = await Directory.systemTemp.createTemp('your_package_prefix_');
  final dylibPath = '${tempDir.path}/${Platform.isWindows ? 'your_lib.dll' : Platform.isMacOS ? 'libyour_lib.dylib' : 'libyour_lib.so'}';
  await File(dylibPath).writeAsBytes(dylibBytes);
  // 加载动态库
  return DynamicLibrary.open(dylibPath);
}

场景3:Flutter全平台适配

如果你开发的是Flutter插件包,直接用Flutter官方的FFI插件模板创建项目即可:

  • Android端:把动态库放到android/src/main/jniLibs/下的对应ABI目录(armeabi-v7a、arm64-v8a等),加载时直接传动态库文件名,系统会自动查找路径。
  • iOS端:把动态库添加到iOS插件的framework依赖中,配置好编译参数,加载时直接传文件名即可。
  • 桌面端:将动态库放到对应平台的打包配置目录中,Flutter打包时会自动把动态库放到可执行文件同级目录,加载时用'${File(Platform.resolvedExecutable).parent.path}/你的动态库文件名'拼接路径即可,该方案在Windows/Linux/macOS下均可用。

内容的提问来源于stack exchange,提问作者azan-n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:09:03