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
{{ message }}
This repository was archived by the owner on Aug 27, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Aug 27, 2026. It is now read-only.
Problem with Android.Graphics.Paint.Color property marshalers #387
The new marshalers we generate are incompatible with the old ones. They use different types. The original ones work with int, while the new ones use Android.Graphics.Color. That means that we return proxy object from the property getter.
The old code:
using Android.Runtime;
using System;
private static Delegate GetGetColorHandler ()
{
if (Paint.cb_getColor == null) {
Paint.cb_getColor = JNINativeWrapper.CreateDelegate (new Func<IntPtr, IntPtr, int> (Paint.n_GetColor));
}
return Paint.cb_getColor;
}
using Android.Runtime;
using Java.Lang;
using System;
private static int n_GetColor (IntPtr jnienv, IntPtr native__this)
{
Paint @object = Java.Lang.Object.GetObject<Paint> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
return @object.Color.ToArgb ();
}
The new marshaler:
using Android.Graphics;
using Java.Interop;
using System;
using System.Reflection;
public static IntPtr n_getColor (IntPtr __jnienv, IntPtr __this)
{
JniTransition jniTransition = new JniTransition (__jnienv);
JniRuntime runtime = default(JniRuntime);
Color color = default(Color);
Java.Interop.ProxyValueMarshaler proxyValueMarshaler = default(Java.Interop.ProxyValueMarshaler);
JniValueMarshalerState jniValueMarshalerState = default(JniValueMarshalerState);
try {
runtime = JniEnvironment.Runtime;
JniRuntime.JniValueManager valueManager = runtime.ValueManager;
valueManager.WaitForGCBridgeProcessing ();
MyPaint value = valueManager.GetValue<MyPaint> (__this);
color = value.Color;
proxyValueMarshaler = new Java.Interop.ProxyValueMarshaler ();
jniValueMarshalerState = proxyValueMarshaler.CreateArgumentState (color, ParameterAttributes.None);
IntPtr handle = jniValueMarshalerState.ReferenceValue.Handle;
return JniEnvironment.References.NewReturnToJniRef (jniValueMarshalerState.ReferenceValue);
IL_006b:;
} catch (Exception ex) when (runtime.ExceptionShouldTransitionToJni (ex)) {
jniTransition.SetPendingException (ex);
return default(IntPtr);
IL_00a9:;
} finally {
proxyValueMarshaler.DestroyArgumentState (color, ref jniValueMarshalerState, ParameterAttributes.None);
jniTransition.Dispose ();
}
IntPtr intPtr = default(IntPtr);
return intPtr;
}
There's also an issue with destroying the state in finally block.
That way, Android.Graphics.Color marshaling can be as IL-efficient as what generator currently emits, without jnimarshalmethod-gen.exe needing to know anything specific about Android.Graphicsc.Color.
Activity
radekdoulik commentedon Oct 24, 2018
I wonder how that could have worked before. The https://jenkins.mono-project.com/job/xamarin-android-pr-builder/4177 was green not so long ago.
jonpryor commentedon Oct 24, 2018
I don't know why it worked before. Unfortunately, we don't upload test-related artifacts to Azure. :-(
I do know what the "problem" is:
Android.Graphics.Colorneeds a "custom value marshaler," a'la: https://github.com/xamarin/java.interop/blob/23372eafa446baf93d80e14a58866d75ad557d26/src/Java.Interop.Export/Tests/Java.Interop/ExportTest.cs#L110-L152That way,
Android.Graphics.Colormarshaling can be as IL-efficient as whatgeneratorcurrently emits, withoutjnimarshalmethod-gen.exeneeding to know anything specific aboutAndroid.Graphicsc.Color.[Mono.Android] Add Android.Graphics.Color value marshaler
[Mono.Android] Add Android.Graphics.Color value marshaler