-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
dart:ffi Struct bit fields #38954
Comments
We do not have support for that yet, but it's a good suggestion. The current workaround would be to write a wrapper in Dart that does the bit-masking: const _boldMask = 0x1;
const _underlineOffset = 1;
const _underlineMask = 0x6;
class ScreenCellAttrs extends Struct {
@Int16()
int bits;
int get bold => bits & _boldMask;
void set bold(int value) {
bits = (bits & ~_boldMask) | (value & _boldMask);
}
int get underline => (bits & _underlineMask) >> _underlineOffset;
void set underline(int value) {
bits = (bits & ~_underlineMask) |
((value << _underlineOffset) & _underlineMask);
}
}
main() {
final p = allocate<ScreenCellAttrs>();
p.ref.bold = 1;
p.ref.underline = 2;
print(p.ref.bold);
print(p.ref.underline);
free(p);
} |
Thanks! For anyone else who comes across this issue, here's a simple mixin I made to make it easier:
|
Issue: #38954 Change-Id: I04b2b81d83a19c5ff88d4364256b23594fe2139b Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122762 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
I've added a full example in the commit above. It uses bit shifts instead of math functions, so it should be a bit faster. We could make writing these bit fields by hand a bit more ergonomic by exposing the int extension, and a predefined set of fixed-size bit field mixins in /// Extension to use a 64-bit integer as bit field.
extension IntBitField on int {
static int _bitMask(int offset, int lenght) => ((1 << lenght) - 1) << offset;
/// Read `length` bits at `offset`.
///
/// Truncates everything.
int getBits(int offset, int length) {
final mask = _bitMask(offset, length);
return (this & mask) >> offset;
}
/// Returns a new integer value in which `length` bits are overwritten at
/// `offset`.
///
/// Truncates everything.
int setBits(int offset, int length, int value) {
final mask = _bitMask(offset, length);
return (this & ~mask) | ((value << offset) & mask);
}
} mixin BitField16 on Struct {
@Int16()
int bits;
int getBits(int offset, int length) => bits.getBits(offset, length);
void setBits(int offset, int length, int value) {
bits = bits.setBits(offset, length, value);
}
} In the end we probably would like to have support for bitfields in a From that perspective, we do not need to add support for bit fields in |
The landed sample is a decent solution. If anyone has problems using that solution, please reopen this issue. |
This needs to be supported in the VM for fully platform agnostic bitfield definitions, see dart-lang/native#406. |
How do we support bit fields in dart:ffi? Something like:
what would be the correct way to represent this from within Dart?
The text was updated successfully, but these errors were encountered: