Dart C 互操作性。将整数数组传递给 C 函数
Dart C Interoperability. Pass an array of integers to C function
我现在正在学习 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 数组作为输入,returns 最大的数字。我怎样才能做到这一点?我已经在 C 中实现了所有必需的代码,但我不确定如何使用 Dart "link" 实现它。有人可以帮帮我吗?
首先,我真的想说我不是 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,并且正在研究 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 数组作为输入,returns 最大的数字。我怎样才能做到这一点?我已经在 C 中实现了所有必需的代码,但我不确定如何使用 Dart "link" 实现它。有人可以帮帮我吗?
首先,我真的想说我不是 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;
}