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

如何通过FFI在Flutter的C++代码中读取资源文件?

在Flutter中让C++读取Asset文件夹中的文件

Flutter的Asset文件打包后会嵌入到App安装包内,没有固定的文件系统路径供C++直接读取,因为不同平台的Asset存储机制不同。以下是两种可行的实现方案:

方案1:直接传递Asset二进制数据给C++(适合小文件)

通过Flutter的rootBundle读取Asset内容,再通过Platform Channel将二进制数据传递给C++层,无需处理路径问题:

Flutter Dart 代码

import 'package:flutter/services.dart';

Future<void> passAssetToCpp() async {
  // 读取Asset文件
  final ByteData assetData = await rootBundle.load('assets/your_data_file.dat');
  final Uint8List bytes = assetData.buffer.asUint8List();
  
  // 通过MethodChannel传递给C++
  await const MethodChannel('asset_reader_channel').invokeMethod('processAssetData', bytes);
}

C++ 代码(以Android JNI为例)

#include <jni.h>
#include <cstddef>

extern "C" JNIEXPORT void JNICALL
Java_com_your_package_name_MainActivity_processAssetData(JNIEnv* env, jobject thiz, jbyteArray byte_array) {
    jsize data_len = env->GetArrayLength(byte_array);
    jbyte* data_buffer = env->GetByteArrayElements(byte_array, nullptr);
    
    // 在这里直接处理二进制数据,比如解析、写入临时文件等
    // ...
    
    // 释放资源
    env->ReleaseByteArrayElements(byte_array, data_buffer, JNI_ABORT);
}

方案2:将Asset复制到可访问路径后由C++读取(适合大文件)

先让Flutter把Asset复制到App的私有沙盒目录(该目录C可直接访问),再将路径传递给C读取:

Flutter Dart 代码

import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

Future<String> copyAssetToAccessiblePath() async {
  // 获取App私有文档目录
  final appDocDir = await getApplicationDocumentsDirectory();
  final targetFile = File('${appDocDir.path}/your_data_file.dat');
  
  // 仅当文件不存在时复制
  if (!await targetFile.exists()) {
    final ByteData assetData = await rootBundle.load('assets/your_data_file.dat');
    await targetFile.writeAsBytes(assetData.buffer.asUint8List());
  }
  
  // 传递文件路径给C++
  await const MethodChannel('asset_reader_channel').invokeMethod('readAssetFromPath', targetFile.path);
  return targetFile.path;
}

C++ 代码(以Android JNI为例)

#include <jni.h>
#include <fstream>
#include <string>

extern "C" JNIEXPORT void JNICALL
Java_com_your_package_name_MainActivity_readAssetFromPath(JNIEnv* env, jobject thiz, jstring file_path) {
    const char* path = env->GetStringUTFChars(file_path, nullptr);
    
    // 打开文件读取内容
    std::ifstream asset_file(path);
    if (asset_file.is_open()) {
        std::string content_line;
        while (std::getline(asset_file, content_line)) {
            // 处理文件内容
        }
        asset_file.close();
    }
    
    // 释放资源
    env->ReleaseStringUTFChars(file_path, path);
}

关键注意事项

  1. 确保在pubspec.yaml中正确声明Asset:
    flutter:
      assets:
        - assets/your_data_file.dat
    
  2. iOS平台上,App沙盒目录默认是C++可访问的;Android平台无需额外权限即可访问App私有目录。

内容的提问来源于stack exchange,提问作者user2385596

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:35:13