02、Flutter FFI 基础数据类型

 
Flutter FFI 学习笔记系列

  1. 《Flutter FFI 最简示例》
  2. 《Flutter FFI 基础数据类型》
  3. 《Flutter FFI 函数》
  4. 《Flutter FFI 字符串》
  5. 《Flutter FFI 结构体》
  6. 《Flutter FFI 类》
  7. 《Flutter FFI 数组》
  8. 《Flutter FFI 内存管理》
  9. 《Flutter FFI Dart Native API》
      
     

  Dart 的数据类型与 C 的数据类型不一样,这就需要了解他们之间的对应关系。
 

1、NativeType

  NativeType 是 Dart 中定义的抽象类,用于表示一种 Native 类型,它无法在 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、C语言数据类型在 Dart 的表示形式

  C 语言的数据类型在 Dart 中的表示形式如下表所示:

Dart 中定义的NativeType C语言中的类型 说明
Pointer * 指针类型
nullptr NULL 空指针
Void void void类型
NativeFunction 函数 函数类型
Struct struct 结构体类型
Int8 int8_t 或 char 有符号8位整数
Uint8 uint8_t 或 unsigned char 无符号8位整数
Int16 int16_t 或 short 有符号16位整数
Uint16 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* 整数类型指针
Float float 单精度浮点类型
Double double 双精度浮点类型
Handle Dart_Handle Dart句柄在C中的表示形式
Opaque opaque 不透明类型,即不暴露其成员。一般用于表示C++中的类
dynamic Dart_CObject Dart对象在C中的表现形式

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;

  Dart 代码:

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、总结

  上面介绍了基础数据类型(intfloat等)的映射,其它类型(如:函数类型、结构体等)将在后面的章节中介绍,欢迎关注。

  
  
  
  
  
 

猜你喜欢

转载自blog.csdn.net/eieihihi/article/details/119118069