首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Dart/Flutter FFI (外部函数接口):在Dart中使用FFI调用带有输出参数的本机函数

Dart/Flutter FFI(外部函数接口)基础概念

FFI(Foreign Function Interface) 是一种允许不同编程语言之间进行交互的机制。在Dart中,FFI允许开发者调用C语言编写的本机函数,反之亦然。这对于需要高性能计算或访问底层系统功能的场景非常有用。

优势

  1. 性能优化:对于计算密集型任务,直接调用C语言编写的函数通常比纯Dart实现更快。
  2. 系统级访问:可以访问操作系统提供的底层功能,如文件系统、网络等。
  3. 复用现有库:可以利用现有的C语言库,无需重新实现。

类型

  • 输入参数:传递给本机函数的参数。
  • 输出参数:本机函数返回的结果。
  • 指针参数:用于传递复杂数据结构或大块数据。

应用场景

  • 图像处理:使用C语言编写的图像处理库。
  • 加密算法:调用现有的加密库进行数据处理。
  • 系统调用:直接与操作系统交互。

示例代码

假设我们有一个C语言函数,它接受一个整数数组并返回其总和:

代码语言:txt
复制
// sum.c
#include <stdint.h>

int32_t sum_array(int32_t* array, int32_t length) {
    int32_t sum = 0;
    for (int32_t i = 0; i < length; i++) {
        sum += array[i];
    }
    return sum;
}

编译这个C文件为共享库:

代码语言:txt
复制
gcc -shared -o libsum.so sum.c

在Dart中使用FFI调用这个函数:

代码语言:txt
复制
import 'dart:ffi';
import 'dart:io';

void main() {
  // 加载共享库
  final DynamicLibrary lib = Platform.isAndroid
      ? DynamicLibrary.open("libsum.so")
      : DynamicLibrary.open("libsum.dylib");

  // 定义函数签名
  final int Function(Pointer<Int32>, Int32) sumArray = lib
      .lookup<NativeFunction<Int32 Function(Pointer<Int32>, Int32)>>("sum_array")
      .asFunction();

  // 创建一个整数数组
  final List<int> numbers = [1, 2, 3, 4, 5];
  final Pointer<Int32> arrayPtr = allocate<Int32>(count: numbers.length);
  for (int i = 0; i < numbers.length; i++) {
    arrayPtr[i] = numbers[i];
  }

  // 调用本机函数
  final result = sumArray(arrayPtr, numbers.length);

  print("Sum: $result");

  // 释放内存
  free(arrayPtr);
}

常见问题及解决方法

1. 找不到共享库

原因:可能是因为共享库没有正确放置在应用程序可以访问的路径中。

解决方法

  • 确保共享库文件(如libsum.so)位于正确的目录。
  • 在Android上,通常需要将其放在<project-root>/android/app/src/main/jniLibs/<abi>/目录下。

2. 类型不匹配

原因:Dart和C语言之间的数据类型可能不匹配。

解决方法

  • 仔细检查Dart中的数据类型与C语言中的数据类型是否一致。
  • 使用Pointer类来处理复杂的数据结构。

3. 内存泄漏

原因:未正确释放分配的内存。

解决方法

  • 使用allocate分配内存后,确保使用free释放内存。

通过以上步骤和示例代码,你应该能够在Dart中成功使用FFI调用带有输出参数的本机函数。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

(译)Dart2.12版本发布,可靠的空安全,dart:ffi正式投入生产

(可以在DartPad中试用。) 那是一个非常简单的错误。在Google内部内部在代码中早期使用null安全性的过程中,我们发现了很多复杂的错误。...Flutter小组发现了一个错误,如果将该错误null传递给中的scene参数,Flutter引擎可能会崩溃Window.render()。...当命名参数被标记为required(在Flutter小部件API中经常发生)并且调用者忘记提供参数时,就会发生分析错误: 5.逐步迁移到无效安全性 因为可靠的安全性是对我们的打字系统的根本改变,所以如果我们坚持强制采用...image 目前,使用dart create和flutter create不启用可靠的空安全创建的新程序包和应用程序。当我们看到大多数生态系统已经迁移时,我们希望在将来的稳定版本中对此进行更改。...这里有一些例子: open_file是用于跨多个平台打开文件的单个API。它使用FFI调用Windows,macOS和Linux上的本机操作系统API。

2.7K20

Dart FFI使用 示例

是什么 Dart FFI(官方地址)是可以在Dart Native平台上运行的Dart移动、命令行和服务器应用上通过Dart FFI来调用C代码的一个技术。...说到底,Dart语言也是因为Flutter使用了它才火起来的,所以Dart FFI技术在Flutter应用中更能发挥它更强大的作用 解决的问题 可以同步调用C API,不像Flutter Channel...一开始就是异步 调用C语言更快,不像之前需要通过Native中转(或者改Flutter引擎代码) 还可以封装替换Flutter Channel达到更快和支持同步的目地 简单使用 为了只看FFI的特性,我先不在...编译C代码 在sample.h中写简单的一个函数 sample.h void hello_world(); 复制代码 在sample.c中实现 sample.c #include #...运行代码 现在,在命令行的项目根目录下运行 dart run bin/main.dart 复制代码 如果输出 Hello World 复制代码 说明调用成功 总结 上面就是Dart FFI简单的示例了,

2.2K40
  • 从 QuickJS 到 Dart VM:稿定跨端渲染工程的运行时演化

    Dart VM 迁移实践经验 FFI(Foreign Function Interface[6])意为外部函数接口,它允许我们在一门语言中调用另一门语言中的函数。...在 BaseObject 的构造器中,先通过 FFI 调用一个返回 Pointer的 C++ 函数,赋值给 ptr 属性。...这部分内容和 QuickJS 等其他引擎很接近,其实也没有什么别的,大概三件事: 在 Dart 侧同步调用 C++ 函数 在 C++ 侧同步调用 Dart 函数 在 C++ 侧异步调用 Dart 函数...对于 Dart FFI 的接入应用,这里列出一些令人印象较为深刻的注意事项: 如果想在 C++ 侧同步调用 Dart 函数,我们的方式是先建立一个用于「接收 Dart 回调函数」的 C++ 函数,然后在...异步情况下,哪怕能够在 C++ 侧拿到 Dart 函数对应的函数指针,也不能直接调用(像 QuickJS 那样执行 JS_Call),否则应用会立刻崩溃。这里必须使用 Port。

    2.5K31

    (译)Dart 2.13 类型别名、改进FFI、优化性能、Docker镜像支持

    json['name'], age = json['age']; Json get json => { 'name': name, 'age': age, }; } 您还可以在命名类的类型别名上调用构造函数...例如,以下代码定义类型别名,以描述包含通用类型的键和type的X值的映射List。通过为类型赋予一个带有单个类型参数的名称,映射的规则结构对代码阅读者来说变得更加明显。...Dart 2.13 FFI变更 在Dart FFI中,我们还有一些新功能,这是我们用于调用C代码的互操作机制。 首先,FFI现在支持具有内联数组的结构。...在大型Flutter应用程序中,表示AOT编译的Dart程序的元数据的内部结构可能会占用相当大的内存。...在过去的一年中,我们一直在重组Dart本机运行时,以消除尽可能多的此类开销。

    2K20

    Flutter ffi实践录

    实践了一下 Flutter 通过 ffi 包调用 native C/C++ 代码,ffi 代表 Foreign function interface (外部函数接口),入门实践 可以在 Flutter...我们使用 DynamicLibrary 来加载 C/C++ 编写的动态库。在 iOS 中,可以直接在源代码目录写,在Android 中则需要在 Gradle 中配置 CMakeList 。...关于C代码的编写和Cmakelist的构建,建议使用 Clion 这个IDE,非常的好用 接着在 Dart 端,可以加载我们的动态库: 在 Android 中最终是以 so 库的形式来动态链接的。...先介绍一下 dart 是如何实现对应的 c函数调用的, DynamicLibrary 中提供了 lookup 方法来查找原生类型符号并返回它在内存中的地址。...在Dart的调用中,我们声明 Function的类型: typedef WriteLogDart = void Function(int,Pointer,int,Pointer<Utf8

    1.9K20

    企业微信超大型工程-跨全平台UI框架最佳实践

    3. dart::ffi 调用 dart 在2.5 之后实现了dart::ffi 来调用c++的接口,并且在flutter上也得到了支持,但是dart::ffi在实践的过程中依然有一些限制条件:  1....第二个问题,如果c++的方法是一个异步接口,c++回调dart,异步回调的核心思路是在dart isolate 启动一个listenPort的监听函数,在c++中,我们可以通过Dart_PostCObject...5. ffi接口自动生成与管理 企业微信在2020年下开始使用flutter作为大型独立应用开发,通过dart::ffi 的方式复用了原有底层的service 架构,在一定程度上提高了开发效率,但是在实际开发过程中...模块,暴露出部分 C++ 接口,使得外部的动态库可以基于这些接口通过 DartVM 调用到 dart 的接口。...在 Dart 的运行环境中 C++ 和 Dart 之间就可以像调用自身的接口一样调用彼此的接口。 3.

    4.4K52

    【Rust blog】Rust + Flutter 高性能的跨端尝试

    每次当外部调用 hello 函数时,会在晋城堆空间中创建一个字符串 ( CString ),并将所有权 ( 释放该字符串所占堆空间的权利 ) 移交给调用者。...在 Build Settings 中 Other Linker Flags 中添加 force_load 的参数。 ?...这是由于在 Dart 中通过动态的方式调用了该库的相关函数,但在编译期间静态分析的时候,这些都是未曾被调用过的无用函数,就被剪裁掉了。要通过 force_load 方式解决这个问题。...next 如何高效的实现 Rust & Dart 部分的通信 我们知道 Flutter 和广大 GUI 库类似,属于单线程模型结合事件系统,因此在主线程中使用 FFI 调用 Rust 部分的代码不能阻塞线程...Dart 语言提供 async/await 语法特性用于在 Flutter 中处理网络请求等阻塞任务。

    2.2K10

    Flutter Web - 优雅的兼容 Flutter App 代码

    那在 Flutter Web 下,继续去使用 MethodChannel 并不合适,官方针对不同平台的适配,也是提供了一种最佳实践,每个功能独立提供自身的实现,让外部使用者无感知。...比如 flutter_svg 在针对 Web 的实现上: export '_file_io.dart' if (dart.library.html) '_file_none.dart'; 就是通过判断是否是...路由适配 在桥接适配中解决了重要的业务调用问题,但还有重要的一点就是路由跳转,这个也是分为2部分需要改造。...路由挂载页面 在 App 中还是用的闲鱼的 flutter_boost (上山容易下山难),所以并没有办法能直接用在 Web 项目中。 在 Web 项目中是用的正统官方推荐的 go_router。...报错如上,原因是它自身的实现 export '_file_io.dart' if (dart.library.html) '_file_none.dart'; 在 web 中是使用 _file_none.dart

    1.6K20

    企业微信Flutter与大型Native工程跨四端融合实践

    跨语言通信层:Flutter 作为上层业务开发,需要与原生进行通信,在通信层,主要包含了通过 dart::ffi 直接调用 c++ 底层能力;通过 channel 调用原生的 api 接口,以及通过 socket...1: 如何高效复用 C++统一跨平台能力 dart 2.15 之后提供了 dart::ffi 的方式调用 c/c++ ,在项目的实际开发过程中,我们也遇到一些大型工程下 ffi 的使用问题: 1: dart...调用 c++操作步骤繁琐, 接口维护和约束困难 2: c++调用 dart 方法只支持静态方法或者顶层函数 3: dart 上开放了指针的分配和释放,调用 c++之后内存管理混乱,容易造成内存泄漏 4...另外调用 c++的接口不再受限于静态方法或者顶层函数,开发调用 c++的接口就跟调用本地的 dart 接口是一样的。...在 rpc 的调用过程中,通过将 rpc 的 transport 层,替换成各个语言之间的调用通道,在 Flutter 上就是利用单个 ffi 接口进行请求的收发,从而达到跨语言调用的目的,在框架内部进行线程以及内存的维护与管理

    3.2K21

    Flutter 3.3发布,带来新的预览版渲染引擎

    Flutter 网页应用程序中的文本选择现在可以像预期的那样——用户可以一次选择多行文本。触控手势在桌面应用程序中的效果变得更好。...使用新的 ui.ImmutableBuffer.fromAsset() 方法加载包含在应用程序中的图像速度更快,使用的内存更少。...在 2022 年 7 月运行的所有 Flutter 应用程序中,超过 80% 都使用了全面空安全。所以 Dart 计划在 2023 年中停止支持没有空安全的 Dart 版本。...用于调用本地 C API 的 Dart 外部函数接口(FFI)现在可以在 iOS 和 macOS 上与 Objective-C 和 Swift 代码交互。...改进的类型推断可以更好地检测一些非空参数的情况。异步代码的体积更小,运行得更快。

    1.4K30

    dart:失之东隅收之桑榆

    开发者体验和运行时效率 在没有太多接触 dart 的时候,我想当然以「既生瑜何生亮」为由不喜欢这门语言。因为尝试 flutter 而「不得不」使用 dart 后,我开始慢慢欣赏这门语言。...我想,这也是大部分语言只照顾一头的原因。 语言特性 大部分时候,flutter 中使用到的 dart 都是在画 UI,而这部分的语法,有编程基础的人看着例子十分钟内都能上手。...但既然因为尝试 flutter 而使用 dart,那么 dart 的语言特性还是需要大致了解一下的。...然而 —— dart 还有另一种玩法,就是我们运行 flutter 在设备模拟器上运行代码的方式: ?...具体接近到什么程度,要看 google 把 flutter/dart 放在一个什么样的战略位置。 结论 这一周在 flutter 上的实验,让我对 dart 的好感度提升了很多。

    1.8K11

    Canonical通过Flutter启用Linux桌面应用程序支持

    它还包括新的UI功能,可以很好地适应桌面,例如Material Density支持和NavigationRail,还可以通过Dart:FFI中的实验与基础桌面OS进行深度集成,并可以访问系统菜单栏和标准对话框...从Flutter访问Linux中的本机代码 除了通过编写Dart来创建Flutter小部件来支持桌面之外,您的Linux桌面应用还可以使用平台渠道或C / C ++的Dart外部功能接口访问所有本机Linux...在pub.dev上可以找到的大多数软件包都是纯Dart的,大多数都可以在Linux应用程序中正常工作。有些软件包(称为插件)中包含特定于一个或多个平台的本机代码。...plugin: flutter flutter-target: lib/main.dart # app's main entry-point file 现在,在带有snapcraft.yaml文件的目录中...对于带有分步说明的示例Linux桌面应用程序,我建议编写Write Flutter桌面应用程序代码实验室,该教程将指导您使用OAuth和GraphQL在Flutter中构建GitHub客户端。

    2.7K20

    【译】Flutter架构综述

    这是一个函数调用中的上下文,比如Theme.of(context),并作为参数提供给build()方法。...在Windows上,Flutter被托管在一个传统的Win32应用程序中,并使用ANGLE渲染内容,这是一个将OpenGL API调用转换为DirectX 11等价物的库。...Foreign Function Interface 对于基于C的API,包括那些可以为Rust或Go等现代语言编写的代码生成的API,Dart提供了一个直接的机制,使用dart:ffi库与本地代码绑定...外来函数接口(FFI)模型可以比平台通道快很多,因为不需要序列化来传递数据。相反,Dart运行时提供了在由Dart对象支持的堆上分配内存的能力,并对静态或动态链接的库进行调用。...FFI适用于除web以外的所有平台,在这些平台上,js包具有同等的作用。 要使用FFI,你要为每个Dart和非托管方法签名创建一个typedef,并指示Dart VM在它们之间进行映射。

    5.6K10

    【Rust日报】2022-09-28 为什么沃尔沃认为你的车里应该有 Rust

    在采访中 Julius 讲述了09年它接触了 Rust 的经历和吸引他的点。...为了实现它,Flutter 自带了MethodChannel 的概念,一个允许编写和调用平台本机代码的跨界接口。...然后,它可以实现无缝集成,这在使用操作系统特定的用户界面或本机访问设备外围设备时必不可少。得益于适当的集成机制,无需再进行任何调整。...另一方面,Rust 在各种生态系统中受到关注,该语言的一个特别有趣的特征是它在几乎任何环境中的适应性。用 Rust 编写的程序可以作为二进制文件公开给许多现代操作系统。...不仅如此,感谢基于 Rust 的代码的外部函数接口 (FFI) 集成可能性,它成为编写平台无关代码并通过 FFI 公开它的可行替代方案。

    32630

    【腾讯经验】闪现社区App网络优化

    层则是网络框架,提供了同步接口和异步接口调用、线程池管理、调度器、请求策略、降级、缓存等一系列功能,主要供业务方直接使用。...[image.png] Lighting内部实现参考了OkHttp3的责任链模式,所有的网络请求通过一系列的拦截器来实现: [image.png] 通过责任链模式,可以解耦请求过程中各个阶段,并且允许外部自定义拦截器进行控制...最后网络请求结束,也会返回一系列请求过程中的性能数据给调用方,调用方可以对比自身的耗时数据。...四、 Flutter网络请求ffi优化 网络Engine下沉到C++还有一个好处就是可以直接提供ffi接口供Flutter调用,ffi提供了Dart直接调用C++的能力,性能比Platform Channel...我们把ffi和MethodChannel的网络请求接口耗时进行上报并对比,数据如下: [image.png] FFI接口耗时仅为5ms,而MethodChannel接口耗时高达25ms,我们统计了最近3

    2.5K72

    基于跨平台的移动应用开发框架研究

    经济学中的“有需求就有市场”在技术领域也适用,Electron就是应需求而生的。wxPythonwxPython和pyqt两者类似,都是用python语言开发。...;FFI编译友好(multiplatform):FFI是可以用一种编程语言写的程序能调用另一种编程语言写的代码的机制,使用Rust可以方便地提供接口给其他语言调用;Rust语言的一些特性,也增强了Tauri...并且 FIDE 中还包含各类扩展插件和接口(支付、人脸识别、音视频、OCR 等),开发者可自主勾选所需的支持插件,从而增强所生成 App 原生能力。...选择Flutter框架进行跨平台应用程序开发的主要原因:高度稳定平稳的开发周期强大的热加载功能DART,AOT编译语言满足各种需求的UI套件Flutter 是最新的跨平台应用程序框架之一,由 Google...Flutter是一个免费的开源跨平台框架,它允许你用一组代码创建一个移动应用程序。它的独特之处在于它使用Dart编程语言,不同于其他跨平台应用框架,Flutter根本不使用JavaScript。

    1.5K70

    Flutter 从 TextField 安全泄漏问题深入探索文本输入流程

    一、CWE-316 事实上如果你使用 TextField 作用密码输入框,这时候你很可能会在安全合规中遇到类似 CWE-316 的警告,主要原因在于:Flutter 在进行文本输入时,和原生平台通信过程中...这个问题目前在 Android、iOS、Linux 等平台都普遍存在,那这个问题是从哪里来的? 这就需要聊到 Flutter 里的文本输入实现流程。...InputMethodManager 实现一些输入相关逻辑,同时本身也实现了 ListenableEditingState.EditingStateWatcher 接口,该接口当有文本输入时会被调用;...另外从目前的 Dart 设计上看, Dart String 对象是不可变的,一旦明文 String 进入 Dart heap,就无法确保它何时会被清理,而且即使在 String 被 GC 之后,它曾经占用的内存也将保持不变...当然,如果你只是使用 String 而不是使用 EditableText ,那么 Dart 上类似 typed data 或者 ffi pointers 的能力,一定程度可以解决此类的问题。

    1.6K30

    Flutter 升级 2.0 填坑指导,带你原地起飞

    其实正如《 Dart 2.12 发布,稳定空安全声明和FFI版本》 里所说,升级到 Flutter 2.0 并不会强制要求你马上使用空声明安全 ,所以我们可以把整个升级适配过程拆解几步来完成,最终完成...另外在我的 dependency_overrides 里可以看到很多带有 # 的注解版本,这些版本都是在遇到冲突之后,为了成功运行一个个添加上去,之后在对应插件更新支持兼容后才注释掉。 ? ?...3、针对空声明安全的调整 在完成上面两个步骤,项目应该就可以在 Flutter 2.0 上运行,那接下来就是把版本升级到空安全声明的支持,当然前提是你想要使用 null safety 。...而比如这类方法报错,一般就是提供的参数和使用参数对应不上,只需要添加上 ? 即可修复。 ? 最后有时也会使用 ! 来暂时完成适配,比如某个参数你确定不会为 null,你可以在使用时通过 !...4、针对迁移中运行的调整 最后,到这里你可能会发现,升级到 dart 1.12之后,适配完 null safety 点 IDE 上的运行发现还是运行不起来,比如下图所示: ?

    5K31
    领券