c++ - 如何使用 dart:ffi 将 Uint8List 转换为 C 等效数据类型
问题描述
我正在尝试将图像发送到我计划使用 dart:ffi 运行的自定义 C++ 代码。我已经成功运行了 hello world 问题,我发送了两个整数并将其中的一些作为另一个整数。
现在我想向它发送整个图像并在我的 C++ 代码上处理它。我可以Uint8List
使用CameraImage
下面的代码
Future<ui.Image> convertCameraImageToUiImage(CameraImage image) async {
imglib.Image libImage = imglib.Image.fromBytes(
image.width,
image.height,
image.planes[0].bytes,
format: imglib.Format.bgra,
);
final c = Completer<ui.Image>();
ui.decodeImageFromPixels(
libImage.getBytes(),
image.width,
image.height,
ui.PixelFormat.rgba8888,
c.complete,
);
return c.future;
}
然后我将其转换为Uint8List
ByteData data = await image.toByteData();
Uint8List bytes = data.buffer.asUint8List();
我的问题是,我应该如何定义查找函数以将 a 发送Uint8List
到 C++ 代码并获取List<bool>
,我的 C++ 函数期望cv::mat
(我可以调整它以接收整数数组)作为参数并发送布尔向量。
这是我尝试过的
final List<bool> Function(Uint8List image) _imageToCode = nativeAddLib
.lookup<NativeFunction<List<bool> Function(List<Uint8List>)>>("imageToCode")
.asFunction();
问题是,bool 和 Uint8List 不是 C++ 支持的类型,因此该函数无法识别它们。我应该如何通过频道发送它。
解决方案
您必须分配数据,然后将数据复制到Pointer<something>
. 然后,您导出的 C 函数可以有一个something*
参数。您还需要传递数据的长度。由于目标是构建一个cv::Mat
您可能想要传递几何图形,并从中推断数据长度。
因此,如果您导出的 C 函数具有签名:
void process(int32_t width, int32_t height, uint8_t *bytes);
您的两个 Dart typedef 将是:
typedef process_func = Void Function(Int32 width, Int32 height, Pointer<Uint8> bytes);
typedef ProcessFunc = void Function(int width, int height, Pointer<Uint8> bytes);
在查找中使用那些
_process = nativeLib
.lookup<NativeFunction<process_func>>('process')
.asFunction();
要分配缓冲区,首先import 'package:ffi/ffi.dart';
并使用allocate
var outBuf = allocate<Uint8>(count: outSize);
然后使用 for 循环复制数据。或者使用asTypedData
onoutBuf
获取 aUint8List
并使用setAll
.
使用后请记住free
缓冲区。
(由于您的像素是 rgba8888,它们适合无符号的 32 位整数。您可能希望Uint32
在指针中传递 s,并使用 s 获取它们data.buffer.asUint32List()
。)
你想返回一个bool
. bool
不支持您必须传递一个列表,例如,Int8
您已将值分别设置为 1 和 0。(如果您的列表有界且大小合理,则可以使用位图。例如,如果您知道它始终是 32 位长,则将这些位打包成 32 个 1 和 0 的 Uint32。)
有几种返回列表的策略,其中 list in当然ffi
意味着Pointer<something>
。
如果列表是有界的,您可以在 Dart 端分配它,将指针传递给函数并让 C 函数填充值,也许返回它填充的数字的整数。
如果列表是无限的,则必须允许 C 访问malloc
它,因为只有 C 函数知道它需要多少空间。您现在需要返回 2 个值:指针和长度。由于您只能返回一个值,因此您需要执行诸如传入 a之类的操作Pointer<Int32>
,并让 C 函数为其分配长度。
推荐阅读
- python - Spring Cloud Data Flow Python 脚本处理器不起作用
- python - correc 二维卷积层的输入,给定带有标签的空间数据
- awk - 将一个文件中的行匹配到另一个文件中的列
- react-native - 我如何在 react-native 的生命周期组件中使用 Promise?
- google-sheets - 尝试使用 importxml 将 XE.com 抓取到 GoogleSheets 电子表格中
- python - PYTHON "None" 在列表的末尾被打印在函数中的循环
- google-cloud-platform - GCP:无法初始化 Cloud Shell 编辑器
- python - 在 Pytnon 3.6.5 上使用注释
- spring-boot - 如果服务器发送 2xx 响应但响应在网络上丢失,我会得到什么 HTTP 响应代码?
- spring-boot - @ConfigurationProperties - 在缺少/未解析属性的情况下出现意外行为