【问题标题】:Dart C Interoperability. Pass an array of integers to C functionDart C 互操作性。将整数数组传递给 C 函数
【发布时间】:2021-03-06 01:51:32
【问题描述】:

我现在正在学习 Dart,并且正在玩 Dart 与 C 的互操作性。我能够使用带有两个 int 参数的 C 方法。代码如下:

hello.dart

import 'dart:ffi' as ffi;

typedef sum_func = ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b);
typedef Sum = int Function(int a, int b);
...
final dylib = ffi.DynamicLibrary.open(path);
final sumPointer = dylib.lookup<ffi.NativeFunction<sum_func>>('sum');

final sum = sumPointer.asFunction<Sum>();
print('3 + 5 = ${sum(3, 5)}');

hello.c

int sum(int a, int b){
    return a + b;
}

hello.h

int add(int x, int y)

hello.def

LIBRARY   hello
EXPORTS
   sum

这一切都很好,但我也想要一个max C 方法,它接受一个 int 数组作为输入并返回最大的数字。我怎样才能做到这一点?我已经在 C 中实现了所有必需的代码,但我不确定如何将它与 Dart“链接”。谁能帮帮我?

【问题讨论】:

    标签: c dart interop ffi dart-ffi


    【解决方案1】:

    首先,我真的想说我不是 C 程序员,尤其是在指针方面,我什至没有假装我完全了解如何以最佳方式完成这类事情。

    除此之外,这是我基于此处找到的原始示例的解决方案:https://github.com/dart-lang/samples/tree/master/ffi/primitives

    primitives.dart

    import 'dart:ffi';
    import 'dart:io' show Platform;
    
    import 'package:ffi/ffi.dart';
    
    typedef max_func = Int32 Function(Pointer<Int32> list, Int32 size);
    typedef Max = int Function(Pointer<Int32> list, int size);
    
    void main() {
      var path = './primitives_library/libprimitives.so';
      if (Platform.isMacOS) path = './primitives_library/libprimtives.dylib';
      if (Platform.isWindows) path = r'primitives_library\Debug\primitives.dll';
      final dylib = DynamicLibrary.open(path);
    
      final list = [1, 5, 3, 59030, 131000, 0];
      final listPtr = intListToArray(list);
    
      final maxPointer = dylib.lookup<NativeFunction<max_func>>('max');
      final max = maxPointer.asFunction<Max>();
      print('${max(listPtr, list.length)}'); // 131000
      malloc.free(listPtr);
    }
    
    Pointer<Int32> intListToArray(List<int> list) {
      final ptr = malloc.allocate<Int32>(sizeOf<Int32>() * list.length);
      for (var i = 0; i < list.length; i++) {
        ptr.elementAt(i).value = list[i];
      }
      return ptr;
    }
    

    primitives.h

    int max(int *listPtr, int size);
    

    primitives.c

    #include "primitives.h"
    
    int max(int *listPtr, int size)
    {
      int currentMax = *listPtr;
    
      for (int i = 0; i < size; i++)
      {
        if (currentMax < *listPtr)
        {
          currentMax = *listPtr;
        }
        listPtr++;
      }
    
      return currentMax;
    }
    

    【讨论】:

    • 我们如何对字符串数组做同样的事情?我无法弄清楚如何将字符串数组从 Dart 传递给 c
    • 我建议您创建一个新问题,因为它与当前问题没有太大关系。
    • 这个答案现在似乎无效,因为在新版本的 dart:ffi (pub.dev/packages/ffi/changelog#030-nullsafety0) 中删除了allocate。由于文档似乎很糟糕,任何人都可以正确替换allocate&lt;Int32&gt;(count: list.length)吗?
    • @Siddhant 感谢您的关注。我更新了 Dart 代码,使其与 ffi 包版本 1.0.0 兼容。你可以试试看它是否有效?
    • @julemand101 我认为应该是malloc.allocate&lt;Int32&gt;(sizeOf&lt;Int32&gt;()*list.length);,因为它需要根据github.com/dart-lang/ffi/blob/… 进行字节计数。
    猜你喜欢
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 2013-06-26
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多