native
native copied to clipboard
ffigen still uses ints for struct members.
Consider the header below:
typedef enum A {
enum1,
enum2
} A;
typedef struct B {
A a;
} B;
ffigen generates the following Dart code:
enum A {
enum1(0),
enum2(1);
final int value;
const A(this.value);
static A fromValue(int value) => switch (value) {
0 => enum1,
1 => enum2,
_ => throw ArgumentError("Unknown value for A: $value"),
};
}
final class B extends ffi.Struct {
@ffi.UnsignedInt()
external int a;
}
I found that structs are generated here:
https://github.com/dart-lang/native/blob/2464aaa562f72eae9765a90573417096eccac9ee/pkgs/ffigen/lib/src/code_generator/compound.dart#L154-L159
I'm not sure exactly how the external part works here, so I'm not sure if this can be rewritten to use an enum directly or it has to stay an integer. If it's the latter, this should be sufficient:
final class B extends ffi.Struct {
@ffi.UnsignedInt()
external int _a;
A get a => A.fromValue(_a);
}
That could be implemented by doing:
- s.write('${depth}external ${m.type.getFfiDartType(w)} ${m.name};\n\n');
+ final memberName = m is EnumClass ? '_${m.name}' : m.name;
+ s.write('${depth}external ${m.type.getFfiDartType(w)} $memberName;\n\n');
and then adding:
if (m is EnumClass) {
final enumName = m.getDartType(w);
final memberName = m.name;
s.write('$enumName get $memberName => $enumName.fromValue(_$memberName);\n\n');
}
/cc @dcharkes Should I open a PR with the above or should we do something else? Also, this is technically a breaking change again...
Thankfully, a good workaround in the meantime is using A.fromValue in code that uses B, like:
void main() {
final b = getB();
final result = switch (A.fromValue(b.a) { /* ... */ };
}
final class B extends ffi.Struct { @ffi.UnsignedInt() external int _a; A get a => A.fromValue(_a); }
That would be my first thought indeed. 👍
Also, this is technically a breaking change again...
We're already at 14.0.0-wip due to other breaking changes. So just add another entry to the changelog.
/cc @dcharkes Should I open a PR with the above or should we do something else?
Yes please. 😄 🙏
@dcharkes PR at #1432. Workflows need approval