Skip to content

[Dart FFI] How to pass a Struct via Dart_PostCObject_DL? #47048

@Xwnine

Description

@Xwnine

Cpp Inside

struct Connected {
    uint32_t fd;
    uint32_t connect_type;
    char* local_address;
    uint16_t local_port;
    char* peer_address;
    uint16_t peer_port;
    uint32_t ip_family;
};

DART_EXPORT bool MockPostCObject() {
    Dart_CObject c_event_code;
    c_event_code.type = Dart_CObject_kInt32;
    c_event_code.value.as_int32 = 1;

    Dart_CObject c_mrt_fd;
    c_mrt_fd.type = Dart_CObject_kInt32;
    c_mrt_fd.value.as_int32 = 0;

    char localBuf[100] = "127.0.0.1";
    char peerBuf[100] = "192.168.1.25";

    Connected *cc = (Connected *)malloc(sizeof(Connected));
    cc->fd = 0;
    cc->connect_type = 1;
    cc->local_address = localBuf;
    cc->local_port = 443;
    cc->peer_address = peerBuf;
    cc->peer_port = 443;

    Dart_CObject c_data;
    c_data.type = Dart_CObject_kInt64;
    c_data.value.as_int64 = reinterpret_cast<intptr_t>(&cc);
 

    Dart_CObject* c_request_arr[] = {&c_event_code, &c_mrt_fd, &c_data};
    Dart_CObject c_request;
    c_request.type = Dart_CObject_kArray;
    c_request.value.as_array.values = c_request_arr;
    c_request.value.as_array.length = sizeof(c_request_arr) / sizeof(c_request_arr[0]);

    bool result = Dart_PostCObject_DL(send_port_, &c_request);
    return result;
}


Dart side

class Connected extends ffi.Struct {
  @ffi.Uint32()
  external int fd;
  @ffi.Uint8()
  external int connectType;
  external ffi.Pointer<ffi.Uint8> local_address;
  @ffi.Uint16()
  external int local_port;
  external ffi.Pointer<ffi.Uint8> peer_address;
  @ffi.Uint16()
  external int peer_port;
}


class CtsWork {
  final int eventCode;
  final int fd;
  final int? data;

  factory CtsWork.fromCppMessage(List message) {
    return CtsWork._(message[0], message[1], message[2]);
  }

  CtsWork._(this.eventCode, this.fd, this.data);

  @override
  String toString() =>
      "CtsWork(eventCode: $eventCode, fd: $fd, dataAddress: ${data.toString()})";
}

void _handleCppWork(dynamic message) {
  if (message == null) {
    return;
  }

  final request = CtsWork.fromCppMessage(message);
  logDebug("CtsMrt handle message: ${request.toString()} ");

  final dataAddress = request.data as int;
  final event = Pointer<Connected>.fromAddress(dataAddress).ref;
  print("connected port: ${event.local_port}, ip: ${event.local_address}, peerPort:${event.peer_port}, peerIp: ${event.peer_address}, connect_type: ${event.connectType}");
}

and conslog output

flutter: [2021-08-31 05:22:52:938][debug][]Port Message: CtsWork(eventCode: 1, fd: 0, dataAddress: 123145350311448)
flutter: connected port: 80, ip: Pointer<Uint8>: address=0x700002dc6e70, peerPort:59054, peerIp: Pointer<Uint8>: address=0x700002dc6e80, connect_type: 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions