array members of structs in dart:ffi

Issue

I’d like to use Bob Jenkins rng in my flutter projects
https://burtleburtle.net/bob/rand/isaacafa.html

here we have a struct with 2 static buffers in it

/* context of random number generator */
struct randctx
{
  ub4 randcnt;
  ub4 randrsl[RANDSIZ];
  ub4 randmem[RANDSIZ];
  ub4 randa;
  ub4 randb;
  ub4 randc;
};
typedef  struct randctx  randctx;

now in dart:ffi a Struct class can only have members of int, double and Pointer, decorated appropriately.
However, I can’t describe this struct with given NativeTypes.

class _Rand_context extends Struct {
  @Uint32()
  int counter;
  Pointer<Uint32> result;
  Pointer<Uint32> mem;
  @Uint32()
  int a;
  @Uint32()
  int b;
  @Uint32()
  int c;
}

because ctx.result.asTypedList(256) crashes. So what I did is simply change the arrays in the struct to pointers and initialize this way:

randctx* create_context() {
  randctx* ctx = (randctx*)malloc(sizeof(randctx));
  ub4* mem = (ub4*)malloc(sizeof(ub4) * RANDSIZ);
  ub4* res = (ub4*)malloc(sizeof(ub4) * RANDSIZ);
  ctx->randa=ctx->randb=ctx->randc=(ub4)0;
  memset(res, 0, sizeof(ub4) * RANDSIZ);
  memset(mem, 0, sizeof(ub4) * RANDSIZ);
  ctx->randmem = mem;
  ctx->randrsl = res;
  randinit(ctx, TRUE);

  return ctx;
}

This can be handled by asTypedList but I’m not familiar how the GC handles structs, I’m worried that mem and result won’t get free’d up. Is this the case? Or how should I go about this?

Solution

Came up with something:
keep the original struct but add 2 extra pointers for the buffers

struct randctx
{
  ub4 randcnt;
  ub4 randrsl[RANDSIZ];
  ub4 randmem[RANDSIZ];
  ub4* rslptr;
  ub4* memptr;
  ub4 randa;
  ub4 randb;
  ub4 randc;
};
typedef  struct randctx  randctx;

randctx* create_context() {
  randctx* ctx = (randctx*)malloc(sizeof(randctx));
  ctx->randa=ctx->randb=ctx->randc=(ub4)0;
  memset(ctx->randrsl, 0, sizeof(ub4) * RANDSIZ);
  memset(ctx->randmem, 0, sizeof(ub4) * RANDSIZ);
  ctx->memptr = ctx->randmem;
  ctx->rslptr = ctx->randrsl;
  randinit(ctx, TRUE);

  return ctx;
}

and provide the pointers to asTypedList. Seems to work, things are in one place and hopefully, there are no dangling ownerships. Can live with the extra 16 bytes.

Answered By – Producer

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.