You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[generator] Don't avoid blittable types for fields (#1353)
Fixes: dotnet/android#10404
Context: 57f7bc8
Commit 57f7bc8 updated `generator` to "avoid non-blittable types"
in native callback methods, for which there were two non-blittables:
* System.Boolean, which should be marshaled as a System.SByte, and
* System.Char, which should be marshaled as a System.UInt16.
The problem is that this hit a codepath which was *not*
"for native callback methods": field bindings.
Consider [`android.widget.RelativeLayout.LayoutParams.alignWithParent`][0]:
package android.widget;
public /* partial */ class RelativeLayout {
public /* partial */ class LayoutParams {
public boolean alignWithParent;
}
}
which is bound as [`RelativeLayout.LayoutParams.AlignWithParent`][1]:
namespace Android.Widget;
public partial class RelativeLayout {
public new partial class LayoutParams {
[Register]
public bool AlignWithParent {
get => _members.InstanceFields.GetBooleanValue ("alignWithParent.Z", this);
set {
_members.InstanceFields.SetValue("alignWithParent.Z", this, value ? (sbyte)1 : (sbyte)0);
}
}
}
}
The problem is the property setter, which calls
`Java.Interop.JniPeerMembers.JniInstanceFields.SetValue(string, IJavaPeerable, sbyte)`.
Before 57f7bc8, it would instead call
`Java.Interop.JniPeerMembers.JniInstanceFields.SetValue(string, IJavaPeerable, bool)`,
but with 57f7bc8 there are now runtime crashes when boolean fields
are accessed, starting in .NET 10 Preview 2.
The following code fragment:
var p = new RelativeLayout.LayoutParams (1, 2) {
AlignWithParent = true,
};
crashes with:
F droid_boolfiel: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: attempt to access field boolean android.widget.RelativeLayout$LayoutParams.alignWithParent of type boolean with the wrong type byte: 0x709385d8
F droid_boolfiel: java_vm_ext.cc:542] in call to SetByteField
F droid_boolfiel: java_vm_ext.cc:542] from void crc6463d68d2626be2acb.MainActivity.n_onCreate(android.os.Bundle)
Fix this by updating `generator` so that `BoundFieldAsProperty.cs`
uses the parameter as-is when `ISymbol.OnlyFormatOnMarshal`=true.
The binding for `RelativeLayout.LayoutParams.AlignWithParent` becomes:
namespace Android.Widget;
public partial class RelativeLayout {
public new partial class LayoutParams {
[Register]
public bool AlignWithParent {
get => _members.InstanceFields.GetBooleanValue ("alignWithParent.Z", this);
set {
_members.InstanceFields.SetValue("alignWithParent.Z", this, value);
}
}
}
}
i.e. calling `JniPeerMembers.JniInstanceFields.SetValue(string, IJavaPeerable, bool)`.
[0]: https://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams#alignWithParent
[1]: https://learn.microsoft.com/en-us/dotnet/api/android.widget.relativelayout.layoutparams.alignwithparent?view=net-android-34.0
0 commit comments