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) - 使用流程:
- 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层发来的数据 }); } - 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); }
- Dart端通过
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
相关产品推荐
相关产品推荐

