You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台C/C++能否直接回调Dart?相关实现问题咨询

Android平台C/C++直接调用Dart的可行方案

针对你遇到的问题,以下是几种类似FFI的直接交互方案,解决链接或调用问题:

1. 修复Dart_PostCObject的链接问题

Dart_PostCObject是Dart原生API的一部分,在Android平台上它位于Flutter的libflutter.so库中,你需要在CMake配置中正确链接该库并引入Dart头文件:

  • 在CMakeLists.txt中添加Dart头文件路径和链接libflutter.so:
    # 引入Dart和Flutter的头文件
    include_directories(${dart_include_dir} ${flutter_include_dir})
    # 链接libflutter.so
    target_link_libraries(你的库名称
                          ${flutter_ffi_plugin_libs}
                          log)
    
  • 使用流程:
    1. Dart端通过NativeApi.postCObject获取并传递Dart端口(SendPort)到C层:
      import 'dart:ffi';
      import 'dart:isolate';
      
      // 定义C函数签名,用于传递SendPort
      typedef SendPortC = Void Function(Pointer<Void>);
      typedef SendPortDart = void Function(Pointer<Void>);
      
      final sendPortToC = nativeLib.lookupFunction<SendPortC, SendPortDart>('send_port_to_c');
      
      void main() {
        final receivePort = ReceivePort();
        // 将SendPort转换为指针传递给C
        sendPortToC(receivePort.sendPort.nativePort);
        receivePort.listen((data) {
          // 处理C层发来的数据
        });
      }
      
    2. C层保存该端口,需要调用时使用Dart_PostCObject发送数据:
      #include <dart_api.h>
      
      Dart_Port g_dart_port;
      
      void send_port_to_c(Dart_Port port) {
        g_dart_port = port;
      }
      
      void call_dart_from_c() {
        Dart_CObject message;
        message.type = Dart_CObject_kString;
        message.value.as_string = "Hello from C";
        // 发送数据到Dart
        Dart_PostCObject(g_dart_port, &message);
      }
      

2. 使用FFI回调实现直接调用

这是最接近"直接调用Dart函数"的方式,你可以在Dart端将函数指针传递给C层,C层保存后随时调用:

  • Dart端代码:
    import 'dart:ffi';
    
    // 定义C层要调用的Dart函数签名
    typedef DartCallback = Void Function(Int32);
    typedef CCallback = Void Function(Int32);
    
    // 定义C函数,用于注册回调
    typedef RegisterCallbackC = Void Function(Pointer<NativeFunction<CCallback>>);
    typedef RegisterCallbackDart = void Function(Pointer<NativeFunction<CCallback>>);
    
    final nativeLib = DynamicLibrary.open('libyour_lib.so');
    final registerCallback = nativeLib.lookupFunction<RegisterCallbackC, RegisterCallbackDart>('register_callback');
    
    // 要被C调用的Dart顶级函数
    void dartCallback(int value) {
      print("C called Dart with value: $value");
    }
    
    void main() {
      // 将Dart函数转换为指针传给C
      final callbackPtr = Pointer.fromFunction<CCallback>(dartCallback, 0);
      registerCallback(callbackPtr);
    }
    
  • C层代码:
    #include <stdint.h>
    
    typedef void (*Callback)(int32_t);
    Callback g_dart_callback;
    
    void register_callback(Callback callback) {
      g_dart_callback = callback;
    }
    
    void trigger_dart_call() {
      if (g_dart_callback != NULL) {
        // 直接调用Dart函数
        g_dart_callback(123);
      }
    }
    
  • 注意事项:Dart回调必须是顶级函数或静态函数,不能是实例方法;如果需要调用实例方法,可以封装一个静态中间函数,通过全局变量传递实例引用(需注意线程安全)。

3. 关于BinaryMessenger的说明

如果是开发Flutter插件,BinaryMessenger是官方推荐的跨层通信方式,但它依赖Flutter插件框架的封装,纯FFI项目中手动链接StandardMethodCodec确实会遇到依赖问题,这种场景下前两种方案更直接。

内容的提问来源于stack exchange,提问作者user2376889

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:27:21