Дарт C Совместимость. Передать массив целых чисел в функцию C - PullRequest
2 голосов
/ 27 марта 2020

Я сейчас изучаю Дарт и играю с Взаимодействием Дарт с C. Я могу использовать метод C с двумя параметрами типа int. Код ниже:

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)}');

привет. 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. Может ли кто-нибудь помочь мне, пожалуйста?

1 Ответ

1 голос
/ 27 марта 2020

Во-первых, я действительно хочу сказать, что я не 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
  free(listPtr);
}

Pointer<Int32> intListToArray(List<int> list) {
  final ptr = allocate<Int32>(count: 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);

примитивов. 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;
}
...