Dart/Flutter ffi(外部函数接口)本机回调,例如:sqlite3_exec

Posted

技术标签:

【中文标题】Dart/Flutter ffi(外部函数接口)本机回调,例如:sqlite3_exec【英文标题】:Dart/Flutter ffi (Foreign Function Interface) native callbacks eg: sqlite3_exec 【发布时间】:2020-08-15 21:01:53 【问题描述】:

您好,我正在使用 dart:ffi 来构建与我的原生 c/c++ 库的接口。 我需要一种方法来获取从 c 到 dart 的回调作为 sqlite 中的示例:

int sqlite3_exec(
    sqlite3*,                                  /* An open database */
    const char *sql,                           /* SQL to be evaluated */
    int (*callback)(void*,int,char**,char**),  /* Callback function */
    void *,                                    /* 1st argument to callback */
    char **errmsg                              /* Error msg written here */
);

sqlite3_exec 中的第三个参数是指向回调的函数指针。 所以如果我使用ffi在dart中调用这个函数,我需要传递一个函数指针:在dart:ffiPointer类中有一个名为fromFunction的函数,女巫接受一个dart静态函数和一个exceptionalReturn;但只需调用此函数即可获取 dart 托管函数的函数指针:引发 (sigterm) 并且 dart 代码在此过程中不再起作用。

所以我的问题:有什么方法可以在 dart 中获得本机回调,如 Python、c#、..

额外: 有什么办法可以将dartino 包含在flutter 项目中,因为这个ForeignDartFunction 满足了我的需要。

【问题讨论】:

你看过Pointer.fromFunction吗? api.dart.dev/stable/2.8.1/dart-ffi/Pointer/fromFunction.html @julemand101 是的,我做到了,我的问题暗示了这一点,文档没有fromFunction 的示例。 啊抱歉,没看过那部分。 你确定回调是在主线程上进行的,而不是在库中创建的。 @RichardHeap 我没有调用该函数,只是在 dart 中获取回调函数指针,在调用“Pointer.fromFunction”时引发“sigterm” 【参考方案1】:

我有一个例子可以工作。希望您可以根据自己的情况进行调整。

示例 C 函数

EXTERNC int32_t foo(
                    int32_t bar,
                    int32_t (*callback)(void*, int32_t)
                    ) 
    return callback(nullptr, bar);

飞镖代码

首先是typedefs。我们需要两个用于原生函数 foo 和一个用于 Dart 回调。

typedef example_foo = Int32 Function(
    Int32 bar, Pointer<NativeFunction<example_callback>>);
typedef ExampleFoo = int Function(
    int bar, Pointer<NativeFunction<example_callback>>);

typedef example_callback = Int32 Function(Pointer<Void>, Int32);

以及回调的代码

  static int callback(Pointer<Void> ptr, int i) 
    print('in callback i=$i');
    return i + 1;
  

和查找

  ExampleFoo nativeFoo =
    nativeLib.lookup<NativeFunction<example_foo>>('foo').asFunction();

最后,像这样使用它:

  int foo(int i) 
    return nativeFoo(
      i,
      Pointer.fromFunction<example_callback>(callback, except),
    );
  

正如预期的那样,foo(123) 打印 flutter: in callback i=123 并返回 124

【讨论】:

谢谢,我已经有一个工作示例,我会将其标记为正确答案,因为它涵盖了所需的所有内容。 是的,我也应该证明这一点。 static const except = -1; 我的问题是fromFunction 中的第二个参数exceptionalReturn ,dart 要求它是一个常量值,显然 -5(和负值)不是 dart 编译器的常量值/翻译。所以我需要问你,将值存储在名为except 的变量中是否正常工作。 需要注意的是,这只适用于 Dart 创建的线程,所以同步调用,异步回调,即。如果 Sqlite 在线程上执行回调,则创建的 Sqlite 将 NOT 工作,因为它会破坏 Darts 线程并发安全模型,该模型在以下位置进行跟踪:github.com/dart-lang/sdk/issues/37022。

以上是关于Dart/Flutter ffi(外部函数接口)本机回调,例如:sqlite3_exec的主要内容,如果未能解决你的问题,请参考以下文章

FFI

Haskell中PETSc FFI的库设计

FFI实战之对接GO(CGO)

Dart/Flutter - 回调函数的收益

Dart/Flutter - 回调函数中的“yield”

Dart/Flutter:快速检查 404 链接列表