Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vm/ffi] Pointer failure after upgrading nullsafety #45258

Closed
Sunbreak opened this issue Mar 9, 2021 · 3 comments
Closed

[vm/ffi] Pointer failure after upgrading nullsafety #45258

Sunbreak opened this issue Mar 9, 2021 · 3 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-ffi

Comments

@Sunbreak
Copy link

Sunbreak commented Mar 9, 2021

Reproduce

A little long, check: woodemi/twaindsm.dart#2

Summary

/ before upgrading after nullsafety
empty struct
opaque ~ ~
Uint8 pointer
nested struct ~
  • ✅: connect success
  • ❌: connect failure
  • ~: won't compile
class pTW_IDENTITY extends ffi.Struct {}

var identityPtr = ffi.allocate<pTW_IDENTITY>();
var connect = twainDsm.DSM_Entry(identityPtr,
  nullptr, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, parentPtr.cast<Void>());
@Sunbreak
Copy link
Author

Sunbreak commented Mar 9, 2021

When using inlien-array & nested-struct, commenting out ProductFamily & ProductName works. Only commenting out ProductName won't work either.

It could be related to packed struct #38158

class TW_VERSION extends ffi.Struct {
  @ffi.Uint16()
  external int MajorNum;

  @ffi.Uint16()
  external int MinorNum;

  @ffi.Uint16()
  external int Language;

  @ffi.Uint16()
  external int Country;
  
  @ffi.Array(34)
  external ffi.Array<ffi.Int8> Info;
}

class TW_IDENTITY extends ffi.Struct {
  @ffi.Uint32()
  external int Id;

  external TW_VERSION Version;

  @ffi.Uint16()
  external int ProtocolMajor;

  @ffi.Uint16()
  external int ProtocolMinor;

  @ffi.Uint32()
  external int SupportedGroups;

  @ffi.Array(34)
  external ffi.Array<ffi.Int8> Manufacturer;

  // @ffi.Array(34)
  // external ffi.Array<ffi.Int8> ProductFamily;

  // @ffi.Array(34)
  // external ffi.Array<ffi.Int8> ProductName;
}

@srawlins srawlins added library-ffi area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. labels Mar 9, 2021
@Sunbreak
Copy link
Author

After investigating more, I've found the key different is ffi.allocate() before null-safety and ffi.calloc() after null-safety

With full inlien-array & nested-struct support, ffi.malloc() solve the problem

class TW_IDENTITY extends ffi.Struct {
  // ...
  @ffi.Array(34)
  external ffi.Array<ffi.Int8> ProductName;
}

var identityPtr = ffi.malloc<TW_IDENTITY>();
var connect = twainDsm.DSM_Entry(identityPtr, nullptr, DG_CONTROL,
        DAT_PARENT, MSG_OPENDSM, parentPtr.cast<Void>());

Maybe we need some best practise notes there.

And I'll dig deeper later why malloc/calloc matters

@Sunbreak
Copy link
Author

It turns out the key is whether the memory is zero-initialized.

When I manually zero-initialized the malloc pointer, the operation fails as well.

After fill each field correctly as before nullsafety, everything works

It is related to the TWAIN implementation, not to vm/ffi.

Closing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-ffi
Projects
None yet
Development

No branches or pull requests

2 participants