Flutter: 支持在插件框架中与 C/C++ 集成

创建于 2016-11-28  ·  174评论  ·  资料来源: flutter/flutter

如果有一个调用 C/C++ 代码的示例,或者至少如何构建原生代码以及 Flutter 应用程序,那就太好了。 这可能纯粹是一个 Gradle 问题,但对于不是 Gradle 专家的人(例如我)来说,如何解决这个问题并不清楚。


管理员评论:请参阅https://github.com/dart-lang/sdk/issues/34452了解当前状态和其他信息

dart engine framework platform-android plugin new feature

最有用的评论

我们从几个 Google 应用程序中听到了这个要求:

  • 一个这样的应用程序编写了自己的 C++ 库来操作相机以减少延迟。 这些库是特定于平台的,并且经过优化以尽可能快地工作。 以尽可能低的延迟调用这些库对于此类应用程序至关重要。 强迫他们通过 PlatformChannel + JNI 不会在 Android 上实现。

  • 有一些高级移动团队用 C++ 编写业务逻辑组件,以便能够在他们的 Android 和 iOS 实现之间共享它。 Flutter 支持与这些库的直接集成,将进一步巩固其作为现有最佳跨平台框架的地位。

我不认为这是一个_必须有_。 然而,这是 Flutter 可以进一步区别于其他跨平台解决方案的一个领域。

所有174条评论

@jason-simmons 最了解 Gradle。 一旦我们有了 .so,我绝对可以帮助加载它。

我确实发现在 buildSrc 下有另一个用于设置 gradle 构建版本的属性。 更新到 2.2.2 后,我取得了进步,能够验证 .so 加载,并且可以从 Java 调用。

据推测,我们还需要添加一个 C API 来将 HostMessages 从 C/C++ 代码发送到 Dart。

是的,请。 我怀疑 C->Java 回调可能不便宜。

这事有进一步更新吗? 考虑使用 Flutter 构建一个跨平台应用程序,调用编译成共享库的 C++ 代码,这是唯一的主要停止点。

这在今天是可能的( @jtrunick在他的运输应用程序中这样做了),但你必须先通过 Java 或 Obj-C 反弹。

即您可以使用https://flutter.io/platform-channels/从 Dart 与 Obj-C/Java 对话,然后从 Obj-C/Java 调用您的 C++ 代码。 此错误包括为此添加更直接的支持,并可能避免 Obj-C/Java 直通。

由于 Dart VM 是用 C++ 实现的,难道不应该有一种更简单(如果不太安全)的方法来直接调用 C 共享库(比如通过 dlopen)? 基本(不安全/实验性)支持需要多少更改?

是这样的: https :

我们从几个 Google 应用程序中听到了这个要求:

  • 一个这样的应用程序编写了自己的 C++ 库来操作相机以减少延迟。 这些库是特定于平台的,并且经过优化以尽可能快地工作。 以尽可能低的延迟调用这些库对于此类应用程序至关重要。 强迫他们通过 PlatformChannel + JNI 不会在 Android 上实现。

  • 有一些高级移动团队用 C++ 编写业务逻辑组件,以便能够在他们的 Android 和 iOS 实现之间共享它。 Flutter 支持与这些库的直接集成,将进一步巩固其作为现有最佳跨平台框架的地位。

我不认为这是一个_必须有_。 然而,这是 Flutter 可以进一步区别于其他跨平台解决方案的一个领域。

一个这样的应用程序编写了自己的 C++ 库来操作相机以减少延迟。 [...] 强迫他们通过 PlatformChannel + JNI 不会在 Android 上实现。

他们在 Android 上从 C++ 到 Java 再返回的解决方案是什么?

如果真的有必要,我们可以在移动平台上允许 Dart 原生扩展。 现在,我们不公开dart_api.h的符号。 在翻转开关之前,我们需要决定以下几点:

  • 弄清楚如何让 AOT 编译器知道 Dart 代码的唯一入口点来自可能不在主 Flutter 引擎动态库中的方法。 否则,摇树传递可能会摆脱代码。
  • 提供有关构建和打包本机扩展的指南(分别用于 Android 和 iOS 的 Gradle 和 Xcode)。
  • dart_api.h的例程提供一些 ABI 稳定性保证。 虽然它基本上是稳定的,但我相信它仍在不断发展以适应各种模式。

到目前为止,平台渠道机制似乎已经足以满足更简单的用例。

他们在 Android 上从 C++ 到 Java 再返回的解决方案是什么?

我没有深入研究他们的用例。 似乎他们已经用 C++ 编写了所有需要极低延迟通信的位。 我会问他们是否在性能关键用例中使用任何 JNI(我的直觉是没有)。

这真的取决于我们在 Flutter 方面能做什么。 如果我们能够提供比 JNI 快得多的互操作,这对这些团队来说将是一个巨大的胜利。 他们可以缩小他们的 C++ 代码库并更多地转移到应用程序端。 如果我们的互操作性能可与 JNI 相媲美,那么我在这里看不到大胜。 他们可能会继续他们现在正在做的事情并使用 PlatformChannel。

这是为了给这些团队一个额外的理由转向 Flutter。 我还没有听说这是一个阻滞剂,所以相应地优先考虑。

如果我理解您说的正确,您是说当前的解决方案是在 C++ 中拥有所有逻辑(相机 + UI),而在 Java 中使用最少的逻辑,并且希望将此逻辑的 UI 部分移至 Dart,不会失去低延迟 UI<-> 相机交互性。

能说说他们的线程情况吗? 他们是否只有一个用于相机 + 用户界面的线程?

@chinmaygarde可能会通过他目前在

+1

这个问题有什么进展吗?

我们已经在使用djinni跨不同平台共享逻辑。 如果我们可以在 Dart 和 C++ 之间进行互操作,而不必通过 Java/Objc-C 来回切换,那就太好了。

如果 Dart 可以与 C/C++ 集成,我认为移动设备重用大量本机库并且不需要使用 JNI 或 Objective C++ 绑定到特定平台是一个好主意。

你考虑过https://github.com/mono/CppSharp 吗? 他们已经为 C++ 提供了解析和 AST,以及对多种目标语言的支持。 也许您可以为 CppSharp 创建一个 Dart 生成器?

将基于 C++ 的数据库(如 Realm)直接集成到 C++ 中将显着提高性能和开发人员的生产力:-) 通过 JNI 上/下将是一种浪费。

我正在考虑将 Flutter 用于执行计算机视觉的 AR 应用程序(可能使用 OpenCV),高效且直接的 Dart-C++ 互操作将是一个主要的积极点。 我想许多其他在计算方面做具有挑战性的应用程序的人可能也有这种需求。

有人能确认 C++ 互操作仍然不可用吗? 可以使用包来完成吗?

@tofutim Direct c/c++ interop 仍然不可用,因此为什么这个问题仍然存在。 但是,您可以使用平台通道,然后使用 Obj-C/Java 与您的 C++ 代码交互。 它不是很好,但它是我们目前拥有的全部。

有人能确认 C++ 互操作仍然不可用吗? 可以使用包来完成吗?

为了与平台库互操作,平台通道机制仍然是当前的推荐。

可以简单地添加本机扩展文档中描述的更高效的机制。 但是,我不知道从dart_api.h公开的符号有任何 ABI 稳定性保证。 如果@a-siva 和@eseidelGoogle可以确认存在这样的保证,我就可以尽快开始公开这些符号。 或者,我们可以将Tonic 的一个子集作为 C API 的方便包装器,以便从 C++ 中轻松使用。

我的理解是,这个错误是关于提供 C-API 和工具钩子,以便轻松拥有完整的 C/C++ 插件(不需要 Obj-C/Java 填充,但仍然通过平台通道异步)。

我认为我们此时不应该考虑像本机扩展这样的同步方法。 (但老实说,我将其推迟到@Hixie或 @cbracken)。

@塞德尔

我认为我们此时不应该考虑像原生扩展这样的同步方法

这是为什么?

当前调用C代码的方法是Dart -> Java -> C
我们两次穿越JNI ,对吧?
第一次:通过平台渠道dartJava (在幕后使用
第二次: Java -> C通过JNI

例如,从我的项目需求的角度来看,即使没有稳定性保证(例如作为实验性功能),也可以访问dart_api.h已经足够了。 我主要关心的是将大量二进制数据(图像)从 Dart 端移动到C端并返回,而不需要编组,最好是复制。 Unity/Mono实现了这一点

dart-sdk 问题 31960 中我了解到目前的isolates 实现可能不允许在不复制的情况下传递数据(尽管理论上应该可以检测到在isolate A 中创建的缓冲区在传递给isolate B 后不再使用因此它的所有权可以转移,而无需复制..在这方面的任何计划?),但如果至少在一个隔离内没有编组到/从C会很好。

看起来很快就会登陆的 flatbuffers 可以避免编组: https :
或者使用仅使用单个字节字段的 protobuf 消息。

当然,这需要大量的字节复制,因此对于所有用例来说都不是很好。

我在这里听到了至少三种不同的愿望:

  1. 想要一种仅使用 C/C++ 代码轻松编写 Flutter 插件的方法,而无需添加一堆 Java/Obj-C 胶水(这是我对这个错误的最初理解,我绝对认为我们可以/应该做的事情) .
  2. 想要一种快速/低延迟/等将大量数据移入/移出 Dart 的方法。 (大概来自各种语言,包括 C++。这听起来是一个非常有效的案例!我强烈建议提交一个单独的错误,包括一个示例。)
  3. 想要一种使用同步调用/对象扩展 Dart 的方法吗? (例如本机扩展或其他方法?这也是完全可行的。API 稳定性存在潜在困难,我认为我们希望在采取行动之前了解更多有关特定用例的信息。)

阅读上述内容后,我的反馈是我们应该考虑拆分一些额外的错误。 我们肯定需要围绕 C++ 互操作进行一些投资,但是很难从这个长线程中确定我们应该解决哪些确切的用例以及以什么顺序?

感兴趣的各方是否愿意/能够使用他们想要的用例提交新的错误并将它们链接回这里? 很高兴让这个问题保持开放以跟踪对这个问题空间的普遍兴趣。

关于性能和上面的 2.:虽然我确信 Flutter 的 platform_channels 的性能可以提高(并且我们可能需要其他插件/互操作方法来覆盖所有用例),但我们需要一些具体的在我们采取行动之前,Flutter 的 platform_channels 的性能是一个瓶颈的用例(也许它们存在而我还没有见过它们?)。 我在优化系统性能方面的经验是,我的直觉常常是错误的。 尽管 JNI 或 platform_channels 之类的东西感觉像是潜在的瓶颈,但在我们进行测量之前我们实际上不会知道。

再次感谢大家的帮助和反馈!

想要一种仅使用 C/C++ 代码轻松编写 Flutter 插件的方法,而无需添加一堆 Java/Obj-C 胶水(这是我对这个错误的最初理解,我绝对认为我们可以/应该做的事情) .

这也将为 flutter 提供更好的 sqlite 集成 + 有大量用于加密、ssh 和其他东西的 C/Rust 库。 能够轻松使用它会很酷。

@塞德尔

我听到了至少三种不同的愿望

我投给 1。)

通过阅读 Flutter 文档,扩展平台通道以支持 C 应该相当“简单”。
唯一新颖的可能是一种将 _dynamic 共享对象_(s) 加载到当前进程中的方法。

我会想象 _Android-C_-usage 看起来像:

#include <ndk-version.h>
#include "methodchannel.h"
#include "methodchannels.h"

MethodChannel* flutter_channels;

__attribute__((constructor))
void
on_library_load() {
    flutter_channels = NULL;
}

__attribute__((destructor))
void
on_library_unload() {
    while (MethodChannel* channel = MethodChannels_pop(flutter_channels)) {
        MethodChannel_delete(channel);
    }
}

#define str(a) #a

void
{{pluginClass}}_on_method_call(MethodCall* call, Result* result) {
    if (strcmp("getPlatformVersion", call.method) == 0) {
        Result_success(result, "Android " str(__NDK_BUILD__));
    } else {
        Result_not_implemented();
    }
}

void
{{pluginClass}}_register_with(Registrar* registrar) {
    MethodChannel* channel = MethodChannel_new(Registrar_messenger(registrar), "{{projectName}}");
    flutter_channels = MethodChannels_push(flutter_channels, channel);
    MethodChannel_set_call_handler({{pluginClass}}_on_method_call)
}

从概念上讲,至少对于 _Android-C_,您必须决定如何处理 Java 和 C 的组合。

@seidelGoogle
我们目前通过 Java 和 swift 包装器公开 golang 代码,延迟是我们遇到的一个明显问题。
为什么 ?

  • 我们需要在多个平台之间共享业务逻辑。
  • 用于视频和图像功能,如屏幕共享。
  • 对于数据库。

如果您能够在直接级别添加 golang 支持,那将产生巨大的影响!
为移动设备编译 golang 代码也很容易,没有任何 LDFLags 魔法,所以我认为它会很受欢迎。 我知道目前也在使用方法通道的其他一些 golang 编码器。
至于序列化,我们目前使用 Protobufs 和 flatbuffers。

例子:
https://github.com/dnfield/flatbuffers/blob/master/samples/sample_binary.go

在 fuchsia 中,这是通过 FIDL 完成的,它绑定到 c、rust 和 golang。
使用起来非常棒,我一直很喜欢在嵌入式板上尝试 Rust 和 golang。

也应该可以通过 iOS 和 java 公开 fidl 的东西。
这将在手机和桌面上的紫红色和颤动之间提供一个很好的入口。
只是我正在玩的一个想法

@seidelGoogle
Hiixe 告诉我 FIDL 不能在 Flutter 级别完成,因为 FIDL 依赖于 Fuchsia 中来自 zircon 的内核代码。 因此,在 Flutter 中复制 FIDL IPC 样式功能的唯一方法是将 FIDL 版本写入 Flutter 引擎。 但是后来我在玩弄它并注意到它与 Flatbuffers 非常相似。 所以为什么不直接将 FlatBuffers 用于 Flutter 和 Flutter 上的 cpp 或 golang 或 rust 层之间的序列化层。 ?

只需 +1,我们就有了一个使用名为 Superpowered 的库的 Flutter 应用程序。 Superpowered 是用 C++ 编写的,然后我们使用 java 和 JNI 类型的东西与之交互,我们又使用平台通道与 Java 代码交谈。 如果我们可以跳过中间人当然会很好。

这也是因为这阻碍了像 Realm 这样流行的移动库制作颤振版本,因为它们的核心是用 C/C++ 编写的,而且他们也不想处理 java/objc/swift 中间人。

由于这些原因,除了总体稳定性之外,我认为这个问题是目前 flutter 中最需要的变化之一。 (更具体地说,在@eseidelGoogle的列表中排名第一。)

如果您想听到关于在平台扩展中绕过 Java/JNI 的争论(即,不仅仅是为开发人员隐藏/自动化 Java 粘合层),Superpowered 有很多关于该主题的内容: https :

@pnico你能解释一下这是如何争论 Java/JNI 应该被二分的吗? 这似乎只是说您的音频处理代码应该用 C++ 编写。 (这并不意味着您不能通过 JNI 或任何其他方式调用它)

@csga5000你完全正确,这没有任何意义:D JNI 可能不会真正影响性能,除非你试图做更深奥的事情。 我想这确实归结为方便/可维护性,我想也许能够将更多特定于应用程序的代码从 Java/C++ 移到 Dart 中

我认为@pnico是说他可以通过 JINI 调用它,但是 JINI 增加了太多的延迟。
所以性能是问题所在。
是/否?

这可能会对加密相关工作产生巨大影响。

我也假设 Android Things,虽然我没有看到或做过实验
以及 c 和 dart 中时间敏感 gpio 的基准测试超过 a
年。

2018 年 6 月 9 日星期六,Eddy WM, notifications@ github.com 写道:

这可能会对加密相关工作产生巨大影响。


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/flutter/flutter/issues/7053#issuecomment-395927258
或静音线程
https://github.com/notifications/unsubscribe-auth/AFHMcSI2JDHbgv3iYrStDN5mlzkQ8XEkks5t6xxMgaJpZM4K-PLw
.

从那以后有什么进展吗?

在此问题得到解决之前,是否有关于显示如何集成 ac/c++ lib 的示例 flutter 插件的建议? djinni是一个好去处吗?

在解决之前,唯一的方法是集成 c/c++ 编写原生 android 和 ios 代码,然后使用平台通道连接到 dart 代码

我已经实现了使用平台通道的插件(到 jar 文件和 CocoaPods)。 我正在寻找一个示例插件,它展示了如何集成到相同的 c/c++ 库(适用于 android 和 ios)。 有什么建议吗?

@mmcc007这就是你在 java 或 swift 中的做法。

Java: https : use+C%2B%2B&sourceid=opera&ie=UTF-8&oe=UTF-8

斯威夫特: https : = opera = swift+use+C%2B%2B = opera = UTF-8 =UTF-8

如果你真的想要一个例子(这只是我所知道的),你可以看到 superpowered 如何推荐你这样做: https :
请参阅示例文件夹。 例如,在https://github.com/superpoweredSDK/Low-Latency-Android-iOS-Linux-Windows-tvOS-macOS-Interactive-Audio-Platform/tree/master/Examples_Android/SuperpoweredRecorder/app/src/main 中有java/com/superpowered/recorder/MainActivity.java 引用了 cpp/RecorderExample.cpp 中的代码

@csga5000在第一次审查时,它看起来似乎相当直接。 通过一个工作的颤振插件来看看仍然会很好。 谢谢。

+1 为此。 任何使用 c++ 的 flutter 应用程序的工作示例都会受到欢迎

有一个项目为 golang 做这件事,我认为同样的方法
也可以用于 C++。

golang 程序使用的是 jsonrpc。
然后你需要做的就是使用 jsonrpc 在你自己的 golang 代码前面。

那么一切都非常容易。

我认为平台通道只支持 JSON 作为不可知的序列化
格式 ?

2018 年 7 月 18 日,星期三,16:50 Jefferson Bledsoe, notifications@ github.com
写道:

+1 为此。 使用 C++ 的 Flutter 应用程序的任何工作示例都是
很受欢迎


您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/flutter/flutter/issues/7053#issuecomment-405958345
或静音线程
https://github.com/notifications/unsubscribe-auth/ATuCwkPbb9vLdoaEwM-bLhYPZxtyQ5Vjks5uH0sqgaJpZM4K-PLw
.

你好,有消息吗?

只是想知道该线程中是否有人设法将 Superpowered 库直接集成到 Flutter 应用程序中?

是的@skills-up 我们已经做到了。 只是不在开源项目中,所以我无法展示。 但是,如果您更早地看到我的提示,那么您就是这样做的。 不过,您可能需要为每个 CPU 架构构建 Flutter 应用程序

我知道您是通过 JNI/Java 完成的,而不是直接从 dart 完成的。 我想知道是否有可能完全避免特定于平台的代码。

不过,您可能需要为每个 CPU 架构构建 Flutter 应用程序

你的意思是每个架构都有一个单独的应用程序,或者只是指定所有支持的架构?

顺便说一句,我们已经有一个用 Java 本地编写的工作应用程序。 然而,既然我们也必须创建一个 iOS 应用程序,我想知道从未来的可维护性角度来看,在 Flutter 中创建一个应用程序(而不是在 Swift/XCode 上花费精力)是否会更有意义,因为单一代码库的好处。

好。 Realm 等各位大佬提供方法: https :

lukaspili : 我猜大家还在等待:flutter/flutter#7053
bmunkholm: @lukaspili是的,这是肯定的先决条件。

对于它的价值,我也在等待这个。 在你们得到正确的管道之前,不能真正考虑用颤振同上替换 XF 应用程序。 按照目前的情况,Xamarin 在这个部门中脱颖而出。

这个派对迟到了,但这个帖子的+1很大。

我开发桌面应用程序,我的观点是一行代码(用于桌面):

Flutter - Dart + C++ > Qt ? partyTime() : makeDoWithElectronOrQt()

如果 Flutter 能够为 C++ 提供一流的支持,我认为它的通用方法可能是跨平台应用程序开发的绝对赢家,不仅是“移动优先”,而且是世界第一。 Qt 对小型开发者来说价格昂贵,固执己见,不接受现代 C++,没有任何真正的竞争,Flutter 能至少吃掉它的一些 UI 馅饼吗?

PS:我不反对 Dart,它是另一个新的 C#/Go/Rust/etc。 对于一个新平台来说可能是超级高效的竞争语言,但高性能桌面世界(我的兴趣在这里)应用程序坚定地是 C++,具有广泛的操作系统和库支持,一种以自身速度前进的语言(它不是C),我认为 Flutter 值得!

我不认为flutter在不久的将来会支持C++,现在肯定不可能。 对于一个人来说,我非常喜欢 Dart - 用 C++ 编写应用程序,即使有 Flutter 也需要付出更多的努力。 而且我不认为 C++ 直接转换为桌面支持,他们仍然需要编写相当多的代码,无论如何 dart VM 应该适用于桌面。 我认为大多数应用程序的性能可以忽略不计。

我认为谷歌最终希望支持互操作性,因此您可以使用任何支持的语言甚至这些语言的组合为任何和所有平台编写 Flutter 应用程序。 但我不会期望直到 Fuchsia 发布时或之后。 目前,他们的目标是让编写一次代码变得容易。 Dart 符合该目标,因为它易于使用/学习、高效,并且无论如何都是谷歌的一种语言。 对于拥有一流 C++ 支持的普通用户,我真的认为几乎没有任何实际优势。 性能在移动应用程序中可以忽略不计,并且使用带有 C++ 的平台通道对于与现有 C++ 库进行交互会很方便。 从好的方面来说,您可以确定他们最终打算让 Flutter 支持桌面(至少是 Fuchsia 的水豚,但我怀疑他们会就此止步)。

该线程是关于支持从 dart/flutter 与 C++ 直接集成,这有望在不久的将来出现。

我认为 flutter 不会支持 C++
对于拥有一流 C++ 支持的普通用户,我真的认为几乎没有任何实际优势。

这不是关于 Flutter/Dart 与 C++ 相比有多棒,而是更多关于为了适应当前生态系统而需要的集成点/易用性。 一长串库以共享对象(OpenCV 为例)的形式存在,它们是行业标准,您不能指望人们在 Dart 中重写它们吗?

性能在移动应用程序中可以忽略不计,并且使用带有 C++ 的平台通道对于与现有 C++ 库进行交互会很方便。

恰恰相反,在这种情况下使用通道是次优的,考虑一下您需要在内存(图像)上使用大型二进制对象的用例,您需要:
1- 将这些二进制文件从/复制到 C++ 内存
2- 使用 JNI 与库交互(并处理动态分配给这些二进制文件的指针)
更不用说使用通道产生的序列化/反序列化值/参数成本的开销。

一个好的框架是它引入的新功能/范式与与当前生态系统/遗留系统集成的难易程度之间的平衡,我们不能否认 C++ 是其中的一部分。

@nhachicha @csga5000并不反对直接集成 C++ 的重要性; 他正在回复之前的评论,询问是否可以直接从 C++ 中使用Flutter,而不需要任何 Dart 代码。

性能在移动应用程序中可以忽略不计,并且使用带有 C++ 的平台通道对于与现有 C++ 库进行交互会很方便。
@nhachicha我完全同意。

事实是对于不需要咬牙切齿的性能(很多)的应用程序,那么为什么不将难以掌握的 C++ 换成更高效的东西,事实上,为什么只停留在 Dart,为什么不插入这些超级流行的任何一个,(比 Dart 更流行/成熟的语言:

  • C#/.Net Core 运行时
  • Javascript/Typescript V8 运行时(那时你几乎有了浏览器,但那又​​怎样)
  • Rust(也很快!)
  • 语言
  • Python
  • [在此插入您最喜欢的]...

尽管我个人每天都喜欢并使用其中的一些语言,但 C 和 C++ 是 Linux 的核心,因此 Android、iOS 和桌面平台,如 Windows、MacOS 和其他桌面。 上述语言(包括 Dart)中有一半是用 C++ 编写的。 尖端技术一次又一次地需要调整本机性能,例如 AI(Tensorflow 是 C++,Caffe C++,Pytorch 是 Python 下的 C 等)、增强现实库、AAA 游戏引擎以及任何需要接近 GPU 的东西(CUDA) ,从 C/C++ 调用)。

出于同样的原因, Flutter 渲染引擎本身是用 C++ 编写的(本机、高性能、电池/内存/CPU 效率高),我认为在需要时解锁最佳性能会是超级的,而不会接近托管运行时并且只支持 C++。 这将使 Flutter 与 Xamarin 和 Nativescript 等其他框架区分开来,这些框架诚实地提供了类似的开发体验(都使用过),只是使用不同的语言,为什么不让 Flutter 变得特别,而不仅仅是“Dart”?

_作为旁注,我完全可以用 C/C++ 编写所有内容,从表单验证到像素着色器,但我并不是假装这是很多人在看这个 repo 的观点 - 那是因为我发现 C++高效的语言 - 然而完全是个人选择。_

这是我们需要 C++ 集成的主要原因之一

https://github.com/realm/realm-object-server/issues/55

C/C++ 集成有两种直接的方法:

  • 在 C++ 中提供方法通道实现
  • 提供 Dart VM 原生扩展支持

不幸的是,这两个都有主要的缺点,使我们无法追求它们:

  • 方法通道是高开销抽象 - 而当需要低开销交互时需要 C/C++ 集成。 这意味着方法通道实际上并不能解决问题。
  • Dart VM 原生扩展要求人们使用 Dart VM C API - 引入过多的外部依赖可能是不可取的,特别是考虑到 API 没有很好地老化并且需要一些严重的重构的事实。

似乎更理想的替代方案是引入dart:ffi - Dart VM 的一个核心组件,它允许直接绑定到本机代码,使人们能够编写如下内容:

import 'dart:ffi' as ffi;

// Bind foo to symbol _foo from library libxyz.so with signature
// int32_t (int32_t, double, char*).
@ffi.import("libxyz.so", name: '_foo',
            signature: ffi.Signature(ffi.Int32, [ffi.Int32, ffi.Double, ffi.PChar]))
extern int foo(int foo, double x, String foo);

长期以来,我们对实施这样的 FFI 抱有一定的兴趣——我希望我们在不久的将来对其进行试验,但我不会承诺任何具体的时间表。

@ kirbyfan64是完全正确的,@nailgilaziev,@bytesoftly我不是说C ++是不需要的整合,我只是说,我不认为有那么多的理由/需求做出镖扑支持C ++ INPLACE -但我并不是说不需要集成。 @mraleph所说的对我来说听起来很聪明。

@mraleph Dartino 对FFI有类似的实现。 复活有多难?

@listepo 的一部分。 Dartino 对 FFI 的实现非常动态——这不是我们想要的 Dart 2,它比 Dart 1 静态得多。

游戏晚了,但这是另一个用例:我们希望在 dart 中包含 c 文件和方法以用于加密目的。

我们希望的是以下内容:
1) iOS 和 Android 的相同代码,即不通过 ObjC 或 JNI 层。
2)希望比通过 JNI 两次时更有效的实现。
3) 可以在后续 Web 应用程序(例如 AngularDart)或使用此项目的后续桌面应用程序中重用 dart 模型代码: https :

我相信我们想要的最接近上面提到的第 2 点@eseidelGoogle 。 至于同步支持,我认为它是一个“很好的拥有”,因为异步函数不能在构造函数中使用,在那里人们可能想要执行例如快速散列计算。 但是习惯了 Darts 异步方式,同步支持似乎不如实现上述 1)-3) 点的一般可能性重要。

按照@mraleph 的建议使用 FFI,这是否允许 1)-3) 像我之前的评论一样,或者这是否意味着在不同的平台(Android、iOS 等)上需要不同的代码?

@CryptUser如果您的 C/C++ 代码在所有平台上都相同,则通过 FFI 调用它的 Dart 代码在所有平台上也相同。

@mraleph听起来很棒! 鉴于原问题有超过 200 个赞,是否有机会提高优先级?

@mraleph Dart 中的 FFI 是否存在未解决的问题?

@dnfield我刚刚提交了一份https://github.com/dart-lang/sdk/issues/34452

我希望能够编写 C/C++/Rust 代码并能够在 ffi 上使用它

例子:

我在 android 平板电脑(Android 4.4)上测试了 flutter。
扑腾跑得飞快。
但是当我尝试使用使用平台通道的 sqflite 读取 1000 行时,速度太慢了。
原因:我不能使用 sqlite 游标阅读器。

但如果我可以直接使用 sqlite 库,同样的查询是即时的。 (使用 xamarin 和本机 android 项目测试)。

我们现在正在讨论如何最好地解决这个问题。 正如上面在 https://github.com/flutter/flutter/issues/7053#issuecomment-377711814 中所述,这个问题有很多部分,可能需要拆分。 :)

但是我们发现一些工程师对探索 FFI 感兴趣(如 https://github.com/flutter/flutter/issues/7053#issuecomment-415161464 中所述)。 我们现在的重点是推出 1.0,但一旦完成,这将在列表中名列前茅。 再次感谢您的持续反馈。 当我们有更多的进展可以分享时,我们会更新这个问题。

我也是 Matlab/Simulink 用户。 我可以生成高度优化的 cpu 特定 c/cpp 代码。 我想将我的算法集成到颤振中。 我有很多图像处理算法。 我需要一个本地代码的绑定生成器。 否则我会忘记我所有的飞镖体验,我会开始学习 xamarin 或适合我的东西。

我们可以加快进度吗?

在 Dart 和 C 之间进行互操作真是太痛苦了。

匆忙的过程不太可能产生高质量的产品。 当它准备好时它就会准备好。 :-)

匆忙的过程不太可能产生高质量的产品。 当它准备好时它就会准备好。 :-)

好吧,我想说的是,我们可能希望提高优先级,以便我们可以投入更多资源和精力来解决这个问题。 您知道,截至目前,有 1386 个未解决的问题针对“目标”,这些问题将“在未来几年内修复”。

再次阅读该线程后,我注意到@eseidelGoogle说在 Flutter 1.0 准备就绪后,这将获得更高的优先级。 我认为它很好地解决了我的担忧。

“目标”可能是错误的桶。 :) @mraleph在我们说话时有人在探索https://github.com/dart-lang/sdk/issues/34452 。 这至少是解决方案的一部分。

这是我们目前在 Dart 端进行原型设计的 FFI的愿景文档

请看一看,让我们知道您的想法。

关于 FFI 部分我不能说太多,因为我从来没有用过这样的东西,
但我想知道 pub 集成会是什么样子。

如何处理使用 FFI 的发布包?
如何处理使用 FFI 的消费包?

@zoechi我们还没有讨论pub集成。

它们应该能够像今天的 Flutter 插件一样工作 - 包括可以编译/链接到消费应用程序的平台/架构适当的源和/或二进制文件。

从 pub 的角度来看,这应该没什么大不了的——除了包中可能包含更大的二进制文件。

尽管需要围绕 Flutter 工具端完成一些工作才能将它们集成到 Flutter 项目中 - 它们的工作方式与今天的 Android/iOS 插件完全不同。

是否应该将 pub-integration 移至 dart-lang/pub 问题以保持该问题更加集中?

我已经阅读了“视觉文档”,我终于在迷雾中看到了形状。

与此同时,我在思考一些非常不同的事情。

即(重新)使用Flatbuffers来制作类似 NativeChannels 的东西。 在执行 (AOT) 时,它将归结为指针传递,而在开发时,它可以让我利用现有工具用于“本机”方面,不仅用 C/C++ 编写,还用 Go 或 Rust 编写。

消息传递方法也更符合当前基于流的架构(Bloc、Rx)。 它也消除了对内存管理的任何担忧,因为编译器可能会在适当的情况下生成合适的环形缓冲区,或者假设简单的“被调用者释放”,其中被调用者需要更长时间地保留数据。

但老实说,如果任何形式的 ffi 能够无缝集成到 Flutter (Fuchsia) 生态系统中,并让我在 Dart 应用程序中使用 CPU 优化的本机代码,我都会为它鼓掌。

@ohir您所设想的将是解决某些问题的另一种解决方案。 这个错误演变成一个通用的包罗万象的任何 C++ 相关的东西。 :/ 我怀疑(正如我在之前的评论中指出的那样)我们需要将此错误分解为较小的错误。 FFI 工作可能不是我们在这个领域构建的唯一解决方案。

@eseidelGoogle在这方面有任何进展吗? 现在我们有一个项目需要实现繁重的视频处理任务,可能通过ffmpeg来完成,由于目前的dart包无法提供可行的解决方案,我们急切地等待flutter直接调用ffmpeg lib。

对于那些基于页面到页面 UI 的应用,现在 Flutter 我觉得比转向 android 和 ios 双重编码工作真的是一个不错的选择,如果我们在 5 年前有这么可爱的设备,整个应用行业可能会被改变。 然而,现在 Flutter 的优势对于迁移到它的公司来说并不是那么惊人,因为他们已经用旧的方式做得足够好,但是对于一些非 UI 任务,dart 远远落后于最高要求。

这并不意味着 dart 有一天不适合这些任务也不可行,但对于可能被纳入 Flutter 生态系统的普通 IT 公司来说,他们需要的是通过使用交叉来降低成本。平台编码方法只有在可以实现最酷的功能时才可以实现,例如客户端数据处理、视频/音频、AR 人员等,只要他们已经通过 c/c++ 完成了一些算法。 他们真的很难使用 dart lang 重新实现或重新发明它。

而关键的解决方案是引入flutter与c++通信的直接高效的方式,我什至认为这是一个“跨平台”的东西的第一要务,dart对于UI人员来说是完美的,一些正常的数据逻辑也可以在 dart 中完成,但让 Flutter 融入长期但仍然活跃且高效的 c++ 生态系统,而不是重建一个神圣的新生态系统要好得多!

真正的“跨平台”编码体验的梦想是让 UI 员工在幕后使用 C++,完全没有 Java 代码,完全没有 oc 代码。 哇哈哈,我迫不及待地想看到它发生!

@smellbee你不能使用 ffmpeg 命令行吗?

@smellbee我失败了,我不是回答这个问题的合适人选。 @eseidelGoogle有这方面的消息吗?

@smellbee你不能使用 ffmpeg 命令行吗?

这是一项客户端工作,使用 ffmpeg lib 渲染视频帧以生成即时反馈流,是否可以使用命令行?

@smellbee我失败了,我不是回答这个问题的合适人选。 @eseidelGoogle有这方面的消息吗?

抱歉,我输入了 "es" ,它自动完成了,我没有注意到......希望@eseidelGoogle可以看到它

Dart 方面的工作正在进行中——我们希望在 2019 年第一季度做好准备。

这是一个很大的特性,我们希望把它做好:因为我们希望它在 Dart 的不同执行模式下都能很好地工作,所以请耐心等待我们制定细节。

您可以关注 dart-lang/sdk#34452,它跟踪 Dart 方面的工作。

Dart FFI 将允许从 Dart 调用 C 函数。
但是 C++ 的特性——类、标准容器、智能指针、异常呢?
我们可以期待以最少的样板将 C++ 类导出到 Dart 的可能性吗?

另一个非常重要的特性是异步支持 - 在单独的线程上运行 C++ 代码并从方法返回 Future/Stream 的能力。

@t-artikov 目前没有直接支持 C++ 互操作性的计划。 这太复杂了。 唯一可以符合人体工程学地与 C++ 互操作的是 C++。

如果您对 C++ 的高级互操作感兴趣,那么您将需要构建自己的互操作层,通过 C 类 API 公开您的 C++ API。

另一个非常重要的特性是异步支持 - 在单独的线程上运行 C++ 代码并从方法返回 Future/Stream 的能力。

我认为这可以构建为一个包。 我们应该确保我们提供正确的原语,以便可以构建它。

Dart FFI 将允许从 Dart 调用 C 函数。
但是 C++ 的特性——类、标准容器、智能指针、异常呢?
我们可以期待以最少的样板将 C++ 类导出到 Dart 的可能性吗?

只要C++有调用dart的方式,我觉得这些都是可能的,C++会照顾C++所担心的,通过被调用或者调用来和dart通信,不需要暴露任何低级的操作给dart 会破坏 dart 的易用性。

另一个非常重要的特性是异步支持 - 在单独的线程上运行 C++ 代码并从方法返回 Future/Stream 的能力。

并且dart已经有了它的异步机制,所以,一个线程是否面向C++没有区别,只要C++部分可以在需要的时候调用dart,一个“Isolate”就可以完成这项工作。

这就是我的想法@mraleph ,如果我错了,请纠正我;)

@mraleph
事实上,有一些很好的 C++ 与其他语言互操作的例子。
https://github.com/boostorg/python
https://github.com/ThePhD/sol2
https://github.com/dropbox/djinni
我希望 Dart/Flutter 能够提供类似的开箱即用机制。

如果您对 C++ 的高级互操作感兴趣,那么您将需要构建自己的互操作层,通过 C 类 API 公开您的 C++ API。

为了说明这种方法是如何适用的,请您使用以下 С++ 类作为示例来演示它:

struct MyObject
{
    std::string name;
    std::vector<int> data;
};

class MyService
{
    // Can throw std::exception
    std::shared_ptr<MyObject> createObject(std::string name, std::vector<int> data);
};

以便它可以从 Dart 中使用

var service = MyService();
var object = service.createObject("foo", [1, 2, 3]);
assert(object.name == "foo");
assert(object.data[0] == 1);

@t-artikov boostorg::pythonsol2实际上很好地说明了我的观点。 请注意,这是用于与其他语言互操作的 C++ 库,而不是相反。 Dart FFI 是一种以 Dart 为中心的调用 C API 的方式,而不是一种以 C++ 为中心的调用 Dart 的方式。

为了说明这种方法是如何适用的,请您使用以下 С++ 类作为示例来演示它:

您将不得不编写(或通过某种工具生成)这样的东西。

// To be compiled together with your code.
typedef std::shared_ptr<MyObject>* MyObjectPtr;

MyService* MyService_create() {
  return new MyService();
}

void MyService_destroy(MyService* ptr) {
  delete ptr;
}

MyObjectPtr MyService_createObject(MyService* ptr, const char* name, int* data, size_t size) {
  try {
    return new std::shared_ptr<MyObject>(createObject());
  } catch (...) {
    return nullptr;
  }
}

const char* MyObject_getName(MyObjectPtr obj) {
  return (*obj)->name.c_str();
}

int* MyObject_data(MyObjectPtr obj) {
  return (*obj)->data.data();
} 

void MyObject_destroy(MyObjectPtr obj) {
  delete obj;
}
// To be included on the Dart side.
@ffi.External()
external Pointer<Void> MyService_create();
@ffi.External()
external void MyService_destroy(Pointer<Void> ptr);
@ffi.External<Pointer<Void> Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Int32)>()
external Pointer<Void> MyService_createObject(Pointer<Void> service, String name, Int32List data, int size);
@ffi.External()
external String MyObject_getName(Pointer<Void> obj);
@ffi.External()
external Pointer<Int32> MyObject_data(Pointer<Void> obj);
@ffi.External()
external void MyObject_destroy(Pointer<Void> ptr);

class MyService {
  final Pointer<Void> _impl;
  MyService() : _impl = ffi.anchor(MyService_create(), MyService_destroy);

  MyObject create(String name, List<int> values) {
    final Int32List data = Int32List.fromList(values);
    return MyObject._(MyService_createObject(_impl, name, data, data.length));
  }

  static _destroy(Pointer<Void> ptr) {
    return MyService_destroy(ptr);
  }
}

class MyObject {
  final Pointer<Void> _impl;

  MyObject._(Pointer<Void> impl) : _impl = anchor(impl, MyObject.destroy);

  String get name => MyObject_getName(_impl);
  Int32List data => MyObject_data(_impl).as<Int32List>();

  static void destroy(Pointer<Void> ptr) { MyObject_destroy(ptr); }
}

请注意,这是用于与其他语言互操作的 C++ 库,而不是相反。

你错了,它们允许将 C++ 类暴露给其他语言。
https://www.boost.org/doc/libs/1_68_0/libs/python/doc/html/tutorial/tutorial/exposing.html

感谢您的 Dart FFI 示例。
有一些缺陷:C++异常应该传递给Dart端; 并且 MyObject.data 不会以这种方式工作(它只获取指针,而不是数据大小)。
但思路很明确。

在我看来,这样的代码太冗长了,无法手动编写。
我期待看到这个过程是否会针对新的 Dart FFI Flutter Engine 绑定实现自动化。

C++ 互操作性的运行时绑定几乎是不可能的(您如何处理泛型、多重继承、运算符重载、损坏的名称等...)。 有很多艰难的尝试(BridJ、CppSharp 等),据我所知,人们发现 C 互操作是最可行的选择。

官方互操作性开发人员不太可能为 C++ 实现非常通用的解决方案。 Kotlin/Native 不提供。 scala-native iether。 .NET(Microsoft C++ 互操作总是奇怪的或静态的)。 JNI 仅在涉及静态编译的情况下支持 C++ 互操作。 像 python boost 胶这样的东西需要手动编写。 任何第三方团队都可以开发 JNAerator 之类的东西(即您可以做到,无需期望 Dart/Flutter 团队能够实现)。

在这次没有真正答案的对话之后,我想我会坚持使用 Qt,它是跨平台的并且具有完整的 C++ 支持。 我只是想在我的下一个项目中尝试一下 Flutter,但现在我不会了,非常感谢!

如果 flutter 是用 C++ 编写的,那么与任何其他语言的互操作将很容易实现,那就更好了。 有没有尝试用 C++ 重写颤振?

我认为讨论现在被不必要地拉长了。

我们知道 Flutter 的开发路线图上有(或没有)什么。
因此,我们可以决定在特定用例中使用(或不使用)它。

我认为试图改变发展议程没有任何用处,或者
超出这一点,需要特定的架构实现。

谢谢,
高拉夫

在 2019 年 2 月 25 日星期一晚上 10:51 bhauj, notifications @github.com 写道:

如果 flutter 是用 C++ 编写的,那就更好了,
与任何其他语言的互操作很容易实现。 是
有没有尝试用 C++ 重写颤振?


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/flutter/flutter/issues/7053#issuecomment-467098455
或静音线程
https://github.com/notifications/unsubscribe-auth/AZ86acDpZgNeyezx40uxe_c5E2xZHWxaks5vRBumgaJpZM4K-PLw
.

实际上,我知道 Flutter 是用 C++ 编写的,但是对于 Flutter 中的编程,只能使用在 VM 中运行的解释器语言 Dart 来完成。 但是你还没有任何机会从 Dart 到 Flutter 的 C++ 部分......

因此,无论谁阅读本文并在 Appdevelopment 中具有良好的跨平台开发的常见用例,如果需要,Flutter 都不会允许直接使用 C++,然后使用另一个跨平台框架,如 Qt C++。

对我来说,C++ 是跨平台开发必不可少的,因为它是几乎所有技术中最低的公分母。

@aqmappdesigners

在 VM 中运行的解释器语言 Dart

那是不准确的。

Flutter 在调试模式下使用 Dart VM,这也使热重载成为可能。
在发布版本中,Dart 被编译为二进制代码,如 C++。

@zoechi谢谢,我不知道这个。 这听起来很适合表演

这听起来很适合表演

并且是 Apples App Store 的要求。

dart:ffi原型已经发展到我们决定 API 决策的地步。 (此处讨论了一些设计决策。)

为了做出明智的设计决策,我们需要更多关于您想要绑定哪些 C API 的示例。 到目前为止,本期提到了 SQLite、Realm、OpenCV、Superpowered 和 ffmpeg。 我们应该考虑其他任何 API 吗?

@dcharkes我不知道它是否有帮助,但是 Android 中的 Telegram 通过 JNI 在 C++ 中进行网络连接:
https://github.com/DrKLO/Telegram/blob/master/TMessagesProj/jni/TgNetWrapper.cpp
它还用ffmpeg处理GIF播放,直接写在Android Bitmaps上:
https://github.com/DrKLO/Telegram/blob/master/TMessagesProj/jni/gifvideo.cpp

有一种方法可以通过libphonenumberlibpostal解析电话和地址glfw + flutter-embedder ,也许有一天我们会看到一个完全用 dart 编写的桌面应用程序。

+1 用于 SQLite 和 Realm。 另请查看Couchbase ,它们具有带有 C SDK 的通用 C++ 核心。

Firebase C++ api 会有趣吗? https://firebase.google.com/docs/reference/cpp/

没有研究太多,但认为可以用一个直接与 C++ 对话的插件来替换 iOS 和 Android 插件。

一些加密库应该像 Rust 中的戒指一样得到一些爱 - https://github.com/briansmith/ring

+1 适用于 OpenCV、Realm、SqlCipher (https://github.com/sqlcipher/sqlcipher)

密码学库。 特别是 libsodium 或 tink。

https://github.com/google/tink

https://libsodium.gitbook.io/doc/

已经有一个 flutter-sodium 库,它通过平台通道与每个平台上的 libsodium 包装器对话,然后与本机对话。

自定义映射库,例如 mapbox-gl https://github.com/mapbox/mapbox-gl-native

Flutter 通过https://github.com/deltachat/deltachat-c​​ore 的SMTP / IMAP 处理(用于通过电子邮件聊天)是我喜欢直接使用的东西。

如果我可以大胆地解释一下,常见的用例如下:

  1. 低延迟音频/视频硬件访问(例如,Superpowered)
  2. 硬件辅助的 a/v 处理(例如,ffmpeg)
  3. 基于 TCP 的套接字访问,用于 XMPP/其他面向网络的协议
    (用于聊天、推送通知)
  4. 进程级升级(root 访问)/在
    跨平台兼容方式(适用于系统应用、多任务、模拟器)

可能还有更多用例,但这些是我想到的主要用例
头脑。

谢谢大家提供的例子! 这非常有帮助。

@skills-up 请注意,我们对具体的例子更感兴趣,而不是抽象的分类。 那是因为我们想通过具体的例子来评估 FFI 的人体工程学。

奇怪的是,通过其强大的宏 + 构建系统提供最佳 C++ 接口的语言之一是 Rust,尽管它具有完全不同的 OO 方法。

我会说 OpenSSL,因为我们需要使用客户端证书对soap 请求和xml 文件(XMLDSig、Xades l)进行数字签名。
Dart 本身有 BoringSSL,但只有一部分通过 Dart 暴露出来。 所以下一个最好的事情是从颤振中调用本机 openssl 库

希望我不是在发垃圾邮件,但我也希望与 tensorflow lite 更好地集成,而不是通过 JNI,这对视频操作非常有用

没有深入研究,但认为可以用一个直接与 C++ 对话的插件替换 iOS 和 Android 插件 >。

除了支持C++,如果有可以直接和Go对话的插件就好了。 现在我们正在谈论通过 gomobile 和 flutter 平台渠道,这会减慢 UI 响应速度。 在 Flutter 中对 Go 和 C++ 的原生支持也将帮助我们为多个平台维护统一的代码库(业务逻辑/算法)。

+1 用于本地图书馆访问。

我想访问 Vulkan/MoltenVK,而不必为 Android/iOS 创建平台渠道并维护两个插件(这也会很大)。 这将允许构建 3D 应用程序并渲染到纹理小部件中,同时只能在 Dart 中进行开发。 平台渠道似乎是一种笨拙的解决方法。 我宁愿访问本机库,而不必为每个平台编写包装器并在该库有新版本时维护它们。
我认为这个功能会吸引更多的开发者。

是的,请直接从 flutter 访问本机库。
我想在flutter中使用一些c++库。

是的,请直接从 flutter 访问本机库。
我想在flutter中使用一些c++库。

现在,我们希望提供早期预览以获取一些反馈。

有关详细信息,请参阅Dart 跟踪错误中

@mit-mit 这对这个问题有帮助吗:我可以调用或使用带有 flutter 的 python 库吗?

聚会迟到,但 SQLCipher @dcharkes @mraleph +1

@doc-rj 我们现在处于您应该能够尝试绑定 SQLCipher 并就您的体验向我们提供反馈的阶段。 看到这个评论

我想强调的是,我们并不是真正的目标是自己提供任何特定的库绑定——因为请求非常多样化,但我们的目标是让每个人和任何人都可以使用 C API 绑定到任何库。

我猜现在已经宣布了多平台,对此的需求会增加。

这是任何路线图的一部分吗?

@felemedeiros工作正在进行中 - 如果您有一个库想要使用 FFI 绑定,我强烈建议您开始处理绑定以向我们提供反馈。 有关信息,请参阅此评论

没有深入研究,但认为可以用一个直接与 C++ 对话的插件替换 iOS 和 Android 插件 >。

除了支持C++,如果有可以直接和Go对话的插件就好了。 现在我们正在谈论通过 gomobile 和 flutter 平台渠道,这会减慢 UI 响应速度。 在 Flutter 中对 Go 和 C++ 的原生支持也将帮助我们为多个平台维护统一的代码库(业务逻辑/算法)。

我写了一篇关于我们目前如何从 Flutter 调用 Go 库 API 的文章。 它可能对感兴趣的人有用。 https://medium.com/@archan.paul/using -go-library-in-flutter-a04e3496aa05

如何在 Flutter 应用程序上添加 C++ 代码?

如何在 Flutter 应用程序上添加 C++ 代码?

我想现在唯一的选择是采用 C++ -> JNI (for Android) -> PlatformChannel 方式,直到我们有更优雅的方式来做同样的事情!

我创建了一个名为 ezored (http://ezored.com) 的项目。 如果我可以将复杂的对象传递给 Flutter 而无需转换为其他东西,那就太好了,因为它已经在 java 和 objc 中了。 任何人都可以使用 ezored 生成 SDK(或下载预构建)来测试原生和 Dart 之间的 Flutter 集成。 它已经实现了请求、解析、使用数据库的 crud 和许多演示 SDK 中的东西。

我在颤振组中搜索,但没有任何方法将对象和对象列表直接传递给颤振。

感谢任何帮助。

有什么新进展吗? 好像过去了2.5年多……

@fzyzcjy我们正在努力。 我们发布了早期预览版。 有关如何参与的信息,请参阅https://github.com/dart-lang/sdk/issues/34452#issuecomment -482136759。

自这个早期预览版以来,我们增加了对 Intel 32、Arm 64 和 Arm 32 的支持。这些平台尚未在稳定版或开发版上发布,它们仅在 Dart sdk 的 master 分支上可用。 这里正在跟踪进展。

@dcharkes很高兴听到这个消息! 感谢您的杰出工作!

任何进展?

有关状态更新和其他信息,请参阅https://github.com/dart-lang/sdk/issues/34452。 最上面的评论有最新的更新。

使用flutter创建Web应用程序时,是否可以将ffi与ac库一起使用?

使用flutter创建Web应用程序时,是否可以将ffi与ac库一起使用?

那不太可能。 从理论上讲,使用 WebAssembly 可以支持更长期,但这不是我们目前正在研究的内容。

@with-with真的吗?

使用flutter创建Web应用程序时,是否可以将ffi与ac库一起使用?

那不太可能。 从理论上讲,使用 WebAssembly 可以支持更长期,但这不是我们目前正在研究的内容。

为什么它需要 WebAssembly? 如果你将来可以要求人们重建到 WebAssembly,你现在可以要求他们重建到 ASM.js。

@nic-hartley 这是个好主意,但挑战不是如何编译本机代码,而是在 Dart(编译为 JS)和本机代码之间建立桥梁,无论它采用什么形式。

出于性能原因,本机 FFI 非常低级,并且无法轻松转换为 asm.js 或 WebAssembly。

澄清一下,我的意思是我们的实现是非常低级的——这当然是一个有趣的功能,但需要大量的工作才能交付。

flutter 只是一个玩具,直到它支持 C++

我来这里是为了回应其他人的相同观点,除非 Flutter 可以轻松地与 C++ 互操作(没有桥接库,也没有性能损失),否则它永远不会被投资于现有本机库或应用程序的大型应用程序采用其中性能是最高优先级。

我会注意到,即使 React Native 目前也使用桥接器,因此似乎 Flutter 在尝试实现 FFI 方面实际上处于领先地位。

在带有 AppKit 的 iOS 上,与 C++ 的集成是微不足道的。 那才是我们应该比较的对象,而不是 React Native。

UWP 和 C++ 也很简单。

不过,我通常也支持“支持 Dart FFI 的努力”派对……

Xamarin 可能比 UWP 更合适,但 Xamarin 的跨平台视图几乎不像 Flutter 那样可定制,并且通常需要大量本机代码才能看起来不错。

这不是真的。 与 Flutter 不同,Xamarin 具有与本机 API(即 Xamarin.iOS 和 Xamarin.Android)的平台绑定,并且应用程序开发人员可以轻松地使用自己的语言(C#/.NET)编写特定于平台的实现。 此问题与语言功能有关,不应与 UI 小部件 API 设计混合。

有很多本机API使用,但没有本机代码调用,Flutter 将在同一条船上(尽管 Xamarin 不需要在那里编写 Java 或 ObjC,应用程序代码中没有反射 hack)。 对于本机代码,即使在 Xamarin.Android 本身(后端平台后端之一),本机代码的使用也很少,应用程序开发人员也没有编写本机代码。

而且与 React Native 或 Xamarin 不同,Flutter 是提供其完整的框架,因此我们将整个 Flutter 框架与 AppKit 之类的东西进行比较是完全公平的观点。

奇怪的是,甚至没有人提到 Qt 框架,它在 C++ 集成方面遥遥领先于其他一切

QT 是 C++。 并且一开始就拥有不利的许可。

2019 年 8 月 12 日,星期一,06:41,弗拉迪斯拉夫·斯泰尔马霍夫斯基,<
[email protected]> 写道:

奇怪的是,甚至没有人提到遥遥领先的 Qt 框架
关于 C++ 集成的其他一切


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/flutter/flutter/issues/7053?email_source=notifications&email_token=AGDYMWXHTJUBUW64LEOO27TQEDSWNA5CNFSM4CXY6LYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJLKTDN5VWWWHZGOD205000000W64LEOO27TQEDSWNA5CNFSM4CXY6LYKYY3PNVWWK3TUL52HS4DFVREXG43
或静音线程
https://github.com/notifications/unsubscribe-auth/AGDYMWTNMTM7QUOY2BEIPM3QEDSWNANCNFSM4CXY6LYA
.

Qt 是 C++ 和 QML(JS 引擎)
什么执照? LGPL? 通用公共许可证? 它有什么问题?

首先是 IANAL,但据我所知,大多数 Qt 是 LGPL(IDE 等是 GPL),这意味着它的语言虽然没有明确禁止静态链接,但如果您的应用程序仍然遵守许可证,则很难做到是闭源的。

从技术上讲,如果您只使用 LGPL 并提供您的目标文件(可能还有说明),以便用户可以重新链接到不同版本的库,那么您就满足了 LGPL 的要求。 但我很确定 Qt 公司不会宣传这个事实,所以普遍的概念是你不能部署静态库,这意味着你不能在不支付他们敲诈勒索的许可费用的情况下让你的应用程序在应用程序商店上发布。 我提供的目标文件可能是错误的,这只是我的理解,我不知道是否有任何公司在这样做。

Android 更容易,因为它确实允许动态加载的库,在 LGPL 下更明确地允许,但老实说,静态链接可能也更可取,以减少应用程序大小,这意味着遇到相同的问题。

@cpboyd ,我想我是从相反的方向看这个的。 我们已经在平台特定的 UI 框架上构建了应用程序,其中每个平台都允许我们利用我们现有的大量 C++ 库。 我知道 Flutter 是跨平台的,这很好,但除非我可以实际使用它(使用我现有的代码),否则我最好坚持使用非跨平台 UI。 唯一的症结在于未来的操作系统(例如 Fuchsia)需要使用 Flutter 和 Dart,但不允许使用这种用例。 在这种情况下,任何拥有大量现有代码库的人都可能会忽略它。

我想我不确定 Flutter / Dart 是否在设计时考虑了“网络”应用程序(即后端在网络上的位置),还是认真考虑了专业桌面应用程序开发人员的需求。 最终,像这样的决定会影响应用商店中许多应用程序的数量和质量。 如果我可以使用 UIKit 为 iOS 编写高质量的专业应用程序,利用数百万行现有代码,但如果我正在为 Fuchsia/Flutter/Dart 开发,我不能(以接近零的性能成本),那么那将成为我不会开发的操作系统和平台。

我的帖子的目的不是将 Flutter 与其他跨平台或非跨平台库进行比较,而是强调对一部分开发人员很重要的用例。

Dart FFI 很有趣,从sqllite示例的_very_ 简要阅读

#include <mylib/mytype.h>
<strong i="11">@implementation</strong> MyView
{
    MyLib::MyType *_pMyType;
}
<strong i="12">@end</strong>

或带有 C++/WinRT 的 UWP:

#include <mylib/mytype.h>
class MyUserControl : public UserControl
{
    MyLib::MyType *_pMyType;
};

谢谢 :-)

@Hixie @MarkIngramUK这两个都不是跨平台的,这是我的观点。
AppKit 仅适用于 Apple,而 UWP 仅适用于 Windows。
也许如果 Flutter 使用 Swift 或 C# 而不是 Dart,那么我们已经拥有相同级别的支持,但这是一个完全不同的论点。
Xamarin 可能比 UWP 更合适,但 Xamarin 的跨平台视图几乎不像 Flutter 那样可定制,并且通常需要大量本机代码才能看起来不错。
我的建议仍然是:如果你想在 C++ 中使用 Flutter,你应该参加 Dart 团队的 FFI 预览并帮助改进对我们所有人的支持😃

此问题与语言功能有关,不应与 UI 小部件 API 设计混合。

@atsushieno当然,这就是为什么这个讨论会在 Dart FFI 论坛上更有成效...... Flutter 是框架。 Dart 是一种语言。

当您将其与以下 Obj-C 类的易用性进行比较时,这些都不是特别吸引人:

@MarkIngramUK我确定这正是 Dart 团队希望在https://groups.google.com/forum/#!forum/dart -ffi 上看到的那种反馈

我有一个名为 ezored (https://ezored.com) 的项目,它是一个 C++ 引导项目,用于 C++ 中的 SDK 和应用程序。 我们在移动项目(android 和 iOS)中使用。 我正在等待 FFI 完成创建一个项目,该项目将使用默认 SDK 进入 flutter。

我们使用 C++ 没有任何问题,并且减少了开发新功能的时间,因为 SDK 在所有平台上都有相同的代码,正如您在默认实现中看到的(poco 项目、openssl、sqlite,特定平台代码集成)与桥代码等)。

在我看来,这是最好的方法:

  • 带有 C++ 后端的 iOS 和 Android(ezored)
  • Flutter 和 C++ 作为后端

随意为项目添加一个开始:)

Kotlin Multiplatform 可能是一种解决方法,而不是完美的想法。 还需要等待https://github.com/dart-lang/sdk/issues/34452

Unity3d 似乎以某种方式将 flutter 移植到他们基于 C# VM [1] 的引擎中——在那个世界里,C# 和 C++ 之间的对话是体面的。 也许值得看看他们的 repo 他们是如何解决一些问题的。 他们声明:“UIWidgets 主要源自 Flutter”。 我还会看看 react native camp 和他们使用 TurboModules 的新方法——他们的解决方案可能比 flutter 方法更有优势,因为将是
1) 同步和异步以及
2)不会有任何编组和
3) 不仅支持 C 还支持 C++

我正在为两个阵营拉拉加油。

[1] https://github.com/UnityTech/UIWidgets

从 Dart 2.5 开始,这个( dart:ffi )现在处于预览状态:
https://medium.com/dartlang/annoucing-dart-2-5-super-charged-development-328822024970

好消息!

嗯...将双簧管与 Flutter 结合使用就足够了吗?...

https://github.com/google/oboe

@rg4real 是的! 但是,您需要编写一些 C 包装器,因为双簧管接口是用 C++ 编写的。

您可以查看https://github.com/flutter/flutter/wiki/Binding-to-native-code-via-FFI以获取有关入门的说明。

您可以重用我为 C# 绑定编写的oboe-c.so ,如果可行的话https://github.com/atsushieno/oboe-sharp/tree/master/native

@sjindel-google ,这是一些很棒的消息!

所以我需要通过创建类和函数来在 C++ 和 C 代码之间建立一座桥梁。 然后我可以使用这些类并从 Dart 代码调用该函数。 我认为这是对的。

@atsushieno ,谢谢。 我在看。 我不确定如何在我的情况下建立桥梁(缺乏经验)。 但是您是否成功实现了精确演奏双簧管的总体目标? 有那么好吗?

@rg4real我这样做只是为了比低延迟音频更简单的 API(与 OpenSLES 相比)。 如果我真的认真对待延迟,那么我不会使用 Xamarin.Android。 如果您在谈论双簧管(或它背后的 AAudio),那么我确实在Fluidsynth 中使用它并且效果很好。 虽然不确定 AAudio 与 OpenSLES 相比“有多好”。

是否有任何关于如何管理内存的指南?

如果 C++ 代码使用 new/malloc 创建内存并返回到 dart 代码,如何释放该内存。

代码
void foo(char** out) {
*out = 新字符[25];
}

如何删除分配给 |out| 的内存来自飞镖代码的变量?

如果您使用的是 Dart 2.5,则Pointer上有一个.free() Pointer 。 如果你在 dev/master 分支上,这个方法移动了package:ffi https://github.com/dart-lang/ffi/blob/master/lib/src/allocation.dart#L70。

根据评论 - “它只能用于以等效于 [allocate] 的方式分配的指针。” - 只有使用allocate() 方法分配内存时才能使用free()。

例如
ffi.指针ptr = ffi.Pointer。分配();
ptr.free();

这是否负责使用 dart 代码中的 new 或 malloc 释放在 C++ 端分配的内存?

只要内存是通过malloc分配的,无论是通过 Dart 还是 C++,它都可以通过free释放。

在 Dart 2.6 中,我们使用DynamicLibrary.lookupFunction("free")来定义 Dart 中的free ,因此它与程序的 C++ 部分中的free完全相同。 (除非您将多个版本的free到您的二进制文件中。)

关闭此问题,因为此功能现已在所有 Flutter 频道中普遍可用(测试版)。 我们正在继续改进这个问题。 对于任何详细问题,请在https://github.com/dart-lang/sdk/issues/new 中归档

使 c++ 类与 c 兼容很麻烦。 请使能够直接调用 C++ 类

+1 我们可以有 C++ 支持吗?

@KaungZawHtet@fzyzcjy - 请考虑

我要锁定这个问题 - 有很多人订阅了它,但它的原始目标已经很清楚地解决了。

是的,对于新问题,请使用此链接提交它们: https : = library-ffi ,area-vm

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

xster picture xster  ·  3评论

eseidelGoogle picture eseidelGoogle  ·  3评论

collinjackson picture collinjackson  ·  3评论

Hixie picture Hixie  ·  3评论

Hixie picture Hixie  ·  3评论