Flutter FFI 学習ノート シリーズ
- 「Flutter FFI の最も単純な例」
- 「Flutter FFI 基本データ型」
- 「フラッターFFI機能」
- 「フラッターFFI文字列」
- 「フラッターFFI構造」
- 「フラッターFFIクラス」
- 「フラッターFFI配列」
- 「Flutter FFIメモリ管理」
- 《Flutter FFIダーツネイティブAPI》
Dart のデータ型は C のデータ型と異なるため、それらの対応を理解する必要があります。
1、ネイティブタイプ
NativeType
これは Dart で定義された抽象クラスで、 Native
type。Dart では構築できず、FFI インターフェイスを介してのみ返すことができます。次のように定義されます。
/// [NativeType]'s subtypes represent a native type in C.
///
/// [NativeType]'s subtypes are not constructible in the Dart code and serve
/// purely as markers in type signatures.
abstract class NativeType {
const NativeType();
}
NativeType
これは抽象型であり、次のように C 言語でさまざまなデータ型を表すための多くのサブクラスがあります。
2. Dart における C 言語のデータ型の表現
Dart における C 言語のデータ型の表現を次の表に示します。
Dart で定義された NativeType | C言語の型 | 説明する |
---|---|---|
ポインタ | * | ポインタ型 |
nullptr | ヌル | ヌルポインタ |
空所 | 空所 | ボイド型 |
ネイティブ関数 | 関数 | 関数の種類 |
構造体 | 構造体 | 構造タイプ |
Int8 | int8_t または char | 符号付き 8 ビット整数 |
Uint8 | uint8_t または unsigned char | 符号なし 8 ビット整数 |
Int16 | int16_t または short | 符号付き 16 ビット整数 |
Win16 | uint16_t または unsigned short | 符号なし 16 ビット整数 |
Int32 | int32_t または int | 符号付き 32 ビット整数 |
Uint32 | int32_t または unsigned int | 符号なし 32 ビット整数 |
Int64 | int64_t または Long Long | 符号付き 64 ビット整数 |
Uint64 | uint64_t または unsigned long long | 符号なし 64 ビット整数 |
IntPtr | int* | 整数型ポインタ |
浮く | 浮く | 単精度浮動小数点型 |
ダブル | ダブル | 倍精度浮動小数点型 |
取り持つ | ダーツハンドル | C での Dart ハンドルの表現 |
不透明 | 不透明な | 不透明な型。つまり、そのメンバーは公開されません。通常、C++ でクラスを表すために使用されます。 |
動的 | Dart_CObject | C での Dart オブジェクトの表現 |
3. 例
以下は、Dart の C で基本的なデータ型を読み取り、書き換える方法を示すコードです:
C コード:
#include <stdint.h>
#define DART_API extern "C" __attribute__((visibility("default"))) __attribute__((used))
DART_API int8_t int8 = -108;
DART_API uint8_t uint8 = 208;
DART_API int16_t int16 = -10016;
DART_API uint16_t uint16 = 20016;
DART_API int32_t int32 = -10032;
DART_API uint32_t uint32 = 20032;
DART_API int64_t int64 = -1000064;
DART_API uint64_t uint64 = 2000064;
DART_API float float32 = 3.1415;
DART_API double double64 = 2.17284949;
ダーツコード:
DynamicLibrary nativeAddLib = Platform.isAndroid
? DynamicLibrary.open("libnative_ffi.so")
: DynamicLibrary.process();
//变量映射
Pointer<Int8> int8 = nativeApi.lookup<Int8>("int8");
Pointer<Uint8> uint8 = nativeApi.lookup<Uint8>("uint8");
Pointer<Int16> int16 = nativeApi.lookup<Int16>("int16");
Pointer<Uint16> uint16 = nativeApi.lookup<Uint16>("uint16");
Pointer<Int32> int32 = nativeApi.lookup<Int32>("int32");
Pointer<Uint32> uint32 = nativeApi.lookup<Uint32>("uint32");
Pointer<Int64> int64 = nativeApi.lookup<Int64>("int64");
Pointer<Uint64> uint64 = nativeApi.lookup<Uint64>("uint64");
Pointer<Float> float32 = nativeApi.lookup<Float>("float32");
Pointer<Double> double64 = nativeApi.lookup<Double>("double64");
//变量值的读取
print("int8=${int8.value}");
print("uint8=${uint8.value}");
print("int16=${int16.value}");
print("uint16=${uint16.value}");
print("int32=${int32.value}");
print("uint32=${uint32.value}");
print("int64=${int64.value}");
print("uint64=${uint64.value}");
print("float32=${float32.value}");
print("double64=${double64.value}");
//变量值的改写
int8.value = 12;
uint8.value = 24;
print("int8=${int8.value}");
print("uint8=${uint8.value}");
//输出结果:
//I/flutter ( 2076): int8=12
//I/flutter ( 2076): uint8=64
//I/flutter ( 2076): int16=25472
//I/flutter ( 2076): uint16=14528
//I/flutter ( 2076): int32=-40128
//I/flutter ( 2076): uint32=80128
//I/flutter ( 2076): int64=-4000256
//I/flutter ( 2076): uint64=8000256
//I/flutter ( 2076): float32=12.565999984741211
//I/flutter ( 2076): double64=8.69139796
//I/flutter ( 2076): int8=12
//I/flutter ( 2076): uint8=24
例証します:
lookup()
返されるPointer<T extends NativeType>
型はポインタ型です。Pointer.value
ポインタが指すメモリの値は、属性を通じて取得および書き換えることができます。Pointer.address
ポインタのアドレスは、属性を通じて取得できます。
4. まとめ
上記では、基本的なデータ型 ( など) のマッピングについて説明しましたint
。float
他の型 (関数型、構造体など) については、次の章で紹介します。注目してください。