flutter 如何创建 dart:ffi 结构体引用

问题描述 投票:0回答:4

我用

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文档搜索,但我不明白。你知道如何创建一个结构作为参考吗?谢谢你。

flutter dart struct ffi
4个回答
5
投票

示例:

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);

4
投票

虽然我迟到了,但还是写了一个完整的例子,以便对其他刚接触 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;
}

1
投票

根据文档,您无法创建 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;
}

0
投票

最近版本中的语法发生了变化。如果我们有以下结构:

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。

© www.soinside.com 2019 - 2024. All rights reserved.