FlutterプロジェクトへのC言語コードの統合と呼び出し
序文
私はしばらくフラッター開発を学習してきましたが、インターフェイスをより適切に描画し、ユーザーと対話する方法の研究にほとんどの時間が費やされており、基礎となるテクノロジーの探求は十分に深くありません。実際、flutter の公式 SDK は、開発者が単に表面に留まるのではなく、flutter アプリケーションの可能性をより深く探求できるようにするための多くの強力なライブラリを開発者に提供します。つい最近、Bluetooth、Wi-Fi、NFC を使用してスマート ハードウェアと対話できるアプリケーションを開発するために Flutter を使用する必要があるプロジェクトがあります。Github には他の人がパッケージ化した使用可能なサードパーティ ライブラリがすでにいくつかありますが、必要な機能をカスタマイズするために、学習プロセスでもある C ライブラリを直接統合してみることにしました。
サポートするかどうか
flutter の公式ドキュメントを参照すると、flutterがローカル C API を呼び出すためのdart:ffi (Foreign Function Interface: 外部関数インターフェイス) ライブラリを公式に提供していることを発見して嬉しい驚きを感じました。C コードを Flutter プロジェクトに統合し、そのメソッドを呼び出す方法を見てみましょう。
注: 現時点では、この機能は明らかに ios、android、macos のみをサポートしており、Web はサポートしていません。Windows をサポートするかどうかはまだ検討中です。。
統合方法
公式に推奨される統合方法は、フラッター プラグインを生成し、プラグイン内の対応するプラットフォーム (ios/android) ディレクトリに C ソース コードを追加し、プラットフォームで指定された方法に従ってコンパイルして最終プログラムにリンクすることです。段階的に見てみましょう。
- プラグインを生成してコマンドを使用します
flutter create --platforms=android,ios --template=plugin native_add
。プラットフォームプラットフォームはサポートされているプラットフォームで、各プラットフォームは対応するディレクトリや関連する設定ファイルなどを生成します。テンプレートは作成されたフラッタープロジェクトのタイプを指します。ここではプラグイン、つまりプラグインの形式を選択します。 。 - C/C++ ソース コードを追加します。例として、ios ディレクトリの Classes パスの下にネイティブ_add.cpp ファイルを追加します (CocoaPods ではソース コードを podspec ファイルよりも高いディレクトリ レベルに置くことはできませんが、Gradle ではこれを許可します) ios フォルダーをポイントしているため、ソース コードを ios ディレクトリに置くことを推奨します)
native_add.cppのコードは次のとおりです。
#include <stdint.h>
extern "C" __attribute__((visibility("default"))) __attribute__((used))
int32_t native_add(int32_t x, int32_t y) {
return x + y;
}
32 ビット加算を実装する C 関数
備考:この文は公式ドキュメントにありますが、Android プラットフォームで
完全に理解していない場合は
、ソース ファイルのコンパイル方法を定義する CMakeLists.txt ファイルを作成する必要があります。 Gradle でそれらを見つける方法。
cmake_minimum_required(VERSION 3.4.1) # for example
add_library( native_add
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
../ios/Classes/native_add.cpp )
最後に、externalNativeBuild を android/build.gradle ファイルに追加します。例は次のとおりです。
android {
// ...
externalNativeBuild {
// Encapsulates your CMake build configurations.
cmake {
// Provides a relative path to your CMake build script.
path "CMakeLists.txt"
}
}
// ...
}
これにより、最終的に Android プラットフォーム上にダイナミック リンク ライブラリ .so ファイルが生成されます。
- FFI ライブラリを使用してネイティブ コードをバインドします
。 次に、ネイティブ ソース コードを Dart コードに変換するために、lib/native_add.dart ファイルにコードを記述する必要があります。
まず、ネイティブ コードを処理するための DynamicLibrary を作成する必要があります。この手順は iOS と Android で異なります。
import 'dart:ffi'; // For FFI
import 'dart:io'; // For Platform.isX
final DynamicLibrary nativeAddLib = Platform.isAndroid
? DynamicLibrary.open('libnative_add.so')
: DynamicLibrary.process();
//静态链接中的符号可以使用 DynamicLibrary.executable
//或 DynamicLibrary.process 来加载。
//动态链接库在 Dart 中可以通过 DynamicLibrary.open 加载。
Android では、ライブラリの名前は CMakeLists.txt (上記を参照) で定義されますが、iOS ではプラグインの名前 (flutter create コマンドの最後にある名前) が使用されます。
次に、ライブラリ ハンドルを使用してネイティブ メソッドを dart が使用できるメソッドに変換し、native_add シンボルを解決します。
final int Function(int x, int y) nativeAdd = nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>('native_add')
.asFunction();
呼び出しメソッド
統合が成功したかどうかを確認するために、プラグイン プロジェクトのサンプル サブプロジェクト (これは自動的に生成されたアプリ タイプのプロジェクト) の lib/main.dart でこのメソッドの呼び出しを試みることができます。
// Inside of _MyAppState.build:
body: Center(
child: Text('1 + 2 == ${
nativeAdd(1, 2)}'),
),
ただし、ほとんどの場合、このプラグインは通常のアプリ プロジェクトに導入します。
たとえば、native_add プラグインと同じレベルにある flutter_app という名前の新しい Flutter アプリ プロジェクトを作成すると、その依存関係を追加できます。 flutter_appプロジェクトのpubspec.yamlファイル内のnative_add:
dependencies:
native_add:
path: ../native_add/
Flutter_app プロジェクトの main.dart ファイル、native_add パッケージをインポートします。
import "package:native_add/native_add.dart";
最後に、統合されたローカル メソッドを直接呼び出すことができます(もうお分かりか
と思いますが、サンプルのサブプロジェクトの依存関係と、プロジェクトによって自動的に生成されたインポート パッケージの 2 つのステップが実際に行われています)。
プロジェクトにローカル コードを統合して呼び出す方法についての紹介です。次回はより詳細な内容を引き続き検討していきます。ありがとうございました。