Skip to content

Problem with Android.Graphics.Paint.Color property marshalers #387

@radekdoulik

Description

@radekdoulik

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions