ralfbiedert / interoptopus

The polyglot bindings generator for your library (C#, C, Python, …) 🐙
302 stars 27 forks source link

Interoptopus: default packing struct + bool member #100

Closed ralfbiedert closed 4 months ago

ralfbiedert commented 4 months ago

Received this report via mail, in essence:

Default packing RUST structs containing bool members causes unexpected results:

  • RUST bool type is 1 byte, aligned on 4 byte boundaries
  • RUST does not 0 initialize the 3 pad bytes
  • pInvoke return by value by default assumes BOOL types are 4 bytes, and forces any non-0 value to ‘true’ (only tried ‘return by value’, possibly other scenarios behave similarly)

[So when returning an item] with is_valid set to false, C# will randomly see is_valid = true, depending on what happened to be in the 3 pad bytes.

Possible workarounds / fixes:

  • pack the fields using repr packed
  • use an int type (where both sides agree on size) instead of bool
  • In the OverloadWriter emit [MarshalAs(UnamangedType.I1)] for each bool member.