Flutter原生工具链集成插件native_toolchain_c的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter原生工具链集成插件 native_toolchain_c 的使用

native_toolchain_c 是一个用于调用主机上安装的本地 C 编译器的库。该插件目前处于实验阶段,旨在收集反馈并进行改进。

状态:实验性

注意:此包目前是实验性的,并发布在 labs.dart.dev pub 发布者下以征求反馈。

对于发布在 labs.dart.dev 下的包,我们通常计划在一段时间的反馈和迭代后,将包升级为支持的发布者(如 dart.dev、tools.dart.dev),或者停止该包。这些包有更高的 API 和破坏性变更预期。

您的反馈对我们改进这个包非常有价值。如果有问题,请在 bug tracker 中提交问题。

示例代码

以下是一个完整的示例 demo,展示了如何在 Flutter 项目中使用 native_toolchain_c 插件来调用 C 编译器。

创建一个新的 Flutter 项目

首先,创建一个新的 Flutter 项目:

flutter create native_toolchain_demo
cd native_toolchain_demo

添加 native_toolchain_c 依赖

pubspec.yaml 文件中添加 native_toolchain_c 依赖:

dependencies:
  flutter:
    sdk: flutter
  native_toolchain_c: ^0.1.0 # 使用最新版本号

运行 flutter pub get 来获取依赖项。

编写 C 代码

在项目根目录下创建一个名为 c_code 的文件夹,并在其中创建一个简单的 C 文件 hello.c

// c_code/hello.c
#include <stdio.h>

void hello_from_c() {
    printf("Hello from C!\n");
}

编写 Dart 代码

lib 目录下的 main.dart 文件中编写 Dart 代码,调用 C 函数:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Native Toolchain Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _message = "Press the button to call C code";

  void _callCFunction() async {
    final compiler = NativeToolchainC();
    final result = await compiler.compileAndRun('c_code/hello.c');
    setState(() {
      _message = result;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Native Toolchain Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _message,
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _callCFunction,
              child: Text('Call C Function'),
            ),
          ],
        ),
      ),
    );
  }
}

运行项目

确保您已经安装了 C 编译器(例如 GCC),然后运行项目:

flutter run

点击按钮时,Dart 代码会调用 C 函数并在控制台输出 “Hello from C!”,同时更新界面显示结果。

请注意,由于 native_toolchain_c 包还处于实验阶段,可能会有一些不稳定性或需要进一步调整的地方。如果遇到问题,请参考官方文档或提交问题到 GitHub issue tracker


更多关于Flutter原生工具链集成插件native_toolchain_c的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter原生工具链集成插件native_toolchain_c的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中集成并使用原生工具链插件native_toolchain_c的示例。由于native_toolchain_c并非一个实际存在的官方或广泛认可的Flutter插件(可能是一个示例名称),我将提供一个通用的步骤和示例代码,展示如何集成和使用一个自定义的原生C/C++库插件。

步骤 1: 创建Flutter插件项目

首先,确保你已经安装了Flutter和Dart SDK。然后,使用以下命令创建一个新的Flutter插件项目(假设你已经有一个Flutter项目):

flutter create --org com.example --template=plugin my_native_plugin
cd my_native_plugin

步骤 2: 添加C/C++代码

在插件项目中,你需要添加C/C++代码。通常,这会在iosandroid文件夹下分别进行。

iOS

  1. ios/Classes文件夹下创建一个C/C++源文件,例如native_code.cpp
// ios/Classes/native_code.cpp
#include <stdio.h>

extern "C" {
    __attribute__((visibility("default")))
    void helloFromC() {
        printf("Hello from C!\n");
    }
}
  1. 编辑ios/.podspec文件,添加C/C++源文件到编译源中。
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.preserve_paths = 'native_code.cpp'  # 确保源文件被包含
  1. ios/Classes下创建一个头文件,例如NativeToolchainCPlugin.h,声明你要暴露给Dart的函数。
// ios/Classes/NativeToolchainCPlugin.h
#import <Flutter/Flutter.h>

@interface NativeToolchainCPlugin : NSObject<FlutterPlugin>
@end

@implementation NativeToolchainCPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    [FlutterMethodChannel setMethodCallHandler:registrar.messenger() name:@"native_toolchain_c" handler:^(FlutterMethodCall* call, FlutterResult result) {
        if ([@"helloFromC" isEqualToString:call.method]) {
            helloFromC();
            result(nil);
        } else {
            result(FlutterMethodNotImplemented);
        }
    }];
}
@end

Android

  1. android/src/main/cpp文件夹下创建一个C/C++源文件,例如native-lib.cpp
// android/src/main/cpp/native-lib.cpp
#include <jni.h>
#include <string>

extern "C"
JNIEXPORT void JNICALL
Java_com_example_my_native_plugin_NativeToolchainCPlugin_helloFromC(JNIEnv *env, jobject /* this */) {
    __android_log_print(ANDROID_LOG_INFO, "NativeToolchainCPlugin", "Hello from C!");
}
  1. 配置CMakeLists.txtbuild.gradle文件来包含你的C/C++代码。

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library(native-lib SHARED native-lib.cpp)

find_library(log-lib log)

target_link_libraries(native-lib ${log-lib})

android/build.gradle

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
        }
    }
}
  1. android/src/main/java/com/example/my_native_plugin下创建一个Java类,例如NativeToolchainCPlugin.java,并加载你的本地库。
// android/src/main/java/com/example/my_native_plugin/NativeToolchainCPlugin.java
package com.example.my_native_plugin;

import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import android.content.Context;

public class NativeToolchainCPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
    private MethodChannel channel;
    private Context applicationContext;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "native_toolchain_c");
        channel.setMethodCallHandler(this);
        applicationContext = flutterPluginBinding.getApplicationContext();
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        if (call.method.equals("helloFromC")) {
            nativeHelloFromC();
            result.success(null);
        } else {
            result.notImplemented();
        }
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }

    public static native void nativeHelloFromC();

    static {
        System.loadLibrary("native-lib");
    }

    @Override
    public void onAttachedToActivity(ActivityPluginBinding binding) {
        // No-op
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {
        // No-op
    }

    @Override
    public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
        // No-op
    }

    @Override
    public void onDetachedFromActivity() {
        // No-op
    }
}

步骤 3: 在Flutter中使用插件

回到你的Flutter应用项目中,添加对插件的依赖,并在Dart代码中调用C/C++函数。

添加依赖

在Flutter项目的pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  my_native_plugin:
    path: ../my_native_plugin  # 指向你的插件项目路径

调用C/C++函数

在Dart代码中调用:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Native Toolchain Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              try {
                await MyNativePlugin.helloFromC();
              } catch (e) {
                print(e);
              }
            },
            child: Text('Call C Code'),
          ),
        ),
      ),
    );
  }
}

注意:MyNativePlugin.helloFromC()是一个假设的方法,你需要根据你的插件实现来定义它。

总结

以上是一个如何在Flutter项目中集成并使用自定义C/C++原生库的示例。实际的插件名称和API可能会有所不同,但整体流程是类似的。你需要根据你的具体需求调整代码。

回到顶部