Dart FFI使用 Dart调用C函数

1,329 阅读1分钟

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

在Dart与C的交互中,函数调用应该是最常见的场景。下面我们就来看看如何在Dart中调用C的函数,同时也能在C中调用Dart的函数。

Dart调C

无传参无返回值

我们通过一个例子,让Dart来调用C的函数,并在C的函数中输出一句话。

sample.h

void hello_world();

sample.c

void hello_world()
{
    printf("[CPP]: Hello World");
}

main.dart

late final _hello_worldPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('hello_world');
late final _hello_world = _hello_worldPtr.asFunction<void Function()>();
print('[Dart]: ${_hello_world()}');

结果输出

[CPP]: Hello World
[Dart]: null

有返回值

当C有返回值时,可以通过类型转换接收 sample.h

char* getName();

sample.c

char* getName()
{
    return "My name is 大哥大";
}

main.dart

late final _getNamePtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Int8> Function()>>('getName');
late final _getName =
    _getNamePtr.asFunction<ffi.Pointer<ffi.Int8> Function()>();
print("[Dart]: 有返回值 -> "+_getName().cast<Utf8>().toDartString());

输出结果:

[Dart]: 有返回值 -> My name is 大哥大

有传参

利用C的printf函数,实现一个Dart打印函数

sample.h

void cPrint(char *str);

sample.c

void cPrint(char *str) 
{
    printf("[CPP]: %s", str);
    free(str);
}

main.dart

late final _cPrintPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Int8>)>>(
          'cPrint');
late final _cPrint =
    _cPrintPtr.asFunction<void Function(ffi.Pointer<ffi.Int8>)>();
_cPrint("我认为这个输出很有意义".toNativeUtf8().cast<ffi.Int8>());

输出

[CPP]: 我认为这个输出很有意义

这样就实现了一个输出函数了。