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

Flutter Linux平台下如何从原生C++代码调用Dart函数?

在Linux平台Flutter应用中实现C++调用Dart函数

Dart端配置

在Dart层,通过MethodChannel注册方法处理器,接收原生C++端发起的调用:

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';

class NativeBridge {
  static const MethodChannel _channel = MethodChannel('com.example/native_channel');

  static void setupNativeCallback() {
    // 注册方法处理器,响应原生调用
    _channel.setMethodCallHandler((call) async {
      switch (call.method) {
        case 'triggerDartFunction':
          // 解析原生传入的数据
          final data = call.arguments as Map<String, dynamic>;
          print('收到原生数据: ${data['message']}');
          // 执行业务逻辑函数
          _handleNativeEvent(data);
          return 'Dart函数执行完成'; // 可选:返回结果给原生
        default:
          throw MissingPluginException();
      }
    });
  }

  static void _handleNativeEvent(Map<String, dynamic> data) {
    // 这里写你的业务逻辑
    print('处理原生事件ID: ${data['eventId']}');
  }
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  NativeBridge.setupNativeCallback();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('C++调用Dart测试')),
        body: const Center(child: Text('等待原生事件...')),
      ),
    );
  }
}

C++端实现

在Linux原生代码(如main.cc或自定义插件文件)中,获取MethodChannel实例并触发Dart函数调用:

1. 初始化MethodChannel

在Flutter引擎初始化完成后创建通道实例:

#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#include <flutter/flutter_engine.h>
#include <map>
#include <string>

// 全局保存通道实例
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> native_channel;

void InitializeNativeChannel(flutter::FlutterEngine* engine) {
  auto channel = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
      engine->messenger(), "com.example/native_channel",
      &flutter::StandardMethodCodec::GetInstance());
  
  native_channel = std::move(channel);
}

2. 触发Dart函数调用

当原生事件触发时,调用InvokeMethod向Dart发送数据:

// 示例:原生事件触发函数
void TriggerNativeEvent() {
  // 构造传递给Dart的参数
  flutter::EncodableMap arguments;
  arguments[flutter::EncodableValue("message")] = flutter::EncodableValue("来自C++的事件通知");
  arguments[flutter::EncodableValue("eventId")] = flutter::EncodableValue(1001);

  if (native_channel) {
    native_channel->InvokeMethod(
        "triggerDartFunction",
        std::make_unique<flutter::EncodableValue>(arguments),
        // 可选:处理Dart返回的结果
        [](const flutter::MethodResult<flutter::EncodableValue>& result) {
          if (result.IsSuccess()) {
            const auto* value = result.SuccessValue();
            if (value->IsString()) {
              std::string dart_result = std::get<std::string>(*value);
              printf("Dart返回结果: %s\n", dart_result.c_str());
            }
          } else if (result.IsError()) {
            printf("调用失败: %s\n", result.ErrorMessage().c_str());
          }
        });
  }
}

3. 线程安全处理

如果原生事件在非Flutter线程触发,需切换到Flutter任务线程执行调用:

// 切换到Flutter线程执行任务
void RunOnFlutterThread(flutter::FlutterEngine* engine, std::function<void()> task) {
  engine->task_runner()->PostTask(std::move(task));
}

// 后台线程触发事件的示例
void BackgroundThreadEvent(flutter::FlutterEngine* engine) {
  RunOnFlutterThread(engine, []() {
    TriggerNativeEvent();
  });
}

测试验证

  1. 确保Dart和C++端的通道名称完全一致(如com.example/native_channel)
  2. 在原生代码中触发TriggerNativeEvent(比如通过定时器、按钮点击或业务逻辑条件)
  3. 查看Dart控制台输出,确认数据接收和函数执行情况

常见问题

  • 通道名称不匹配:两端通道字符串必须完全相同,否则无法建立通信
  • 参数类型不兼容:使用EncodableMap/EncodableValue处理复杂类型,确保两端解析逻辑一致
  • 线程错误:必须在Flutter线程调用InvokeMethod,否则会导致崩溃或无响应
  • 通道实例为空:确保InitializeNativeChannel在Flutter引擎初始化完成后调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:40:14