我用
dart:ffi
创建了一个结构体。
import 'dart:ffi';
import 'package:ffi/ffi.dart';
class TestStruct extends Struct{
external Pointer<Utf8> strText;
@Int32()
external int nNum;
@Bool()
external bool bIsTrue;
//contstruct
TestStruct(String str, int number, bool state){
strText = str as Pointer<Utf8>;
nNum = number as int;
bIsTrue = state as bool;
}
}
我想创建
TestStruct
的引用并使用它。所以我写了代码。
TestStruct test = TestStruct("Text", 10, true);
但这是一个错误
Subclasses of 'Struct' and 'Union' are backed by native memory, and can't be instantiated by a generative constructor.
Try allocating it via allocation, or load from a 'Pointer'.
我尝试用api文档搜索,但我不明白。你知道如何创建一个结构作为参考吗?谢谢你。
示例:
class InAddr extends Struct {
factory InAddr.allocate(int sAddr) =>
calloc<InAddr>().ref
..sAddr = sAddr;
@Uint32()
external int sAddr;
}
您可以使用 calloc 函数分配它
final Pointer<InAddr> inAddress = calloc<InAddr>();
并释放指针
calloc.free(inAddress);
虽然我迟到了,但还是写了一个完整的例子,以便对其他刚接触 FFI 场景的人有所帮助。
如果这是 dart 代表结构(来自 C)-
import 'dart:ffi';
import 'package:ffi/ffi.dart';
class TestStruct extends Struct{
@Int32()
external int nNum;
@Bool()
external bool bIsTrue;
// IMPORTANT: DO NOT DEFINE A CONSTRUCTOR since struct/union are natively allocated
}
您可以使用 ffi.Pointer 从 dart 实例化,如下所示。
// my_native_helper.dart
final dynamicLibrary = ... ; // load .so/process
void some_function() {
final Pointer<TestStruct > inAddress = calloc<TestStruct >();
inAddress.ref.nNum= 1234;
inAddress.ref.bIsTrue = false;
// ffigen generated method replicating C extern function
// To auto generate this, define the C signature in a header file
dynamicLibrary.receiveFromDart(inAddress);
calloc.free(inAddress);
}
C 方法如下所示。
extern "C" void recieveFromDart(TestStruct* structPtr) {
cout << structPtr->nNum << "/" << structPtr->bIsTrue << endl;
}
根据文档,您无法创建 Struct 类的实例: https://api.flutter.dev/flutter/dart-ffi/Struct-class.html
但是,您通常需要指针。所以你可以想出类似的东西:
static Pointer<InAddr> allocate(int sAddr) {
final pointer = calloc<InAddr>();
pointer.ref.sAddr = sAddr;
return pointer;
}
最近版本中的语法发生了变化。如果我们有以下结构:
final class CLLocationCoordinate2D extends ffi.Struct {
@ffi.Double()
external double latitude;
@ffi.Double()
external double longitude;
}
我们可以这样实例化它:
final coords = Struct.create<CLLocationCoordinate2D>();
coords.latitude = lat.toDouble();
coords.longitude = lng.toDouble();
来自flutter文档:
无法使用生成构造函数创建结构体子类的实例。相反,可以通过 StructPointer.ref、Struct.create、FFI 调用返回值、FFI 回调参数、StructArray 和访问 Struct 字段来创建实例。要创建由本机内存支持的实例,请使用 StructPointer.ref。要创建由 Dart 内存支持的实例,请使用 Struct.create。