-
Notifications
You must be signed in to change notification settings - Fork 54
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
[Java.Interop] Additional marshaler lookup #389
[Java.Interop] Additional marshaler lookup #389
Conversation
Before going to use the proxy object marshaler, try to check the implemented interfaces for custom marshaler. It will be used in XA to marshal IJavaObject based objects, which do not implement IJavaPeerable. That will make it possible to fix with dotnet#388
Once dotnet/java-interop#389 is merged, it should fix dotnet/java-interop#388 Example of updated marshalers: using Android.Runtime; using Java.Interop; using System; public static void n_setAdapter_Landroid_widget_ListAdapter_ (IntPtr __jnienv, IntPtr __this, IntPtr value) { JniTransition jniTransition = new JniTransition (__jnienv); JniRuntime runtime = default(JniRuntime); try { runtime = JniEnvironment.Runtime; JniRuntime.JniValueManager valueManager = runtime.ValueManager; valueManager.WaitForGCBridgeProcessing (); AbsListView value2 = valueManager.GetValue<AbsListView> (__this); IListAdapter listAdapter2 = value2.Adapter = Java.Interop.JavaConvert.FromJniHandle<IListAdapter> (value, JniHandleOwnership.DoNotTransfer); } catch (Exception ex) when (runtime.ExceptionShouldTransitionToJni (ex)) { jniTransition.SetPendingException (ex); } finally { jniTransition.Dispose (); } } and using Android.Runtime; using Java.Interop; using System; public static IntPtr n_getAdapter (IntPtr __jnienv, IntPtr __this) { JniTransition jniTransition = new JniTransition (__jnienv); JniRuntime runtime = default(JniRuntime); try { runtime = JniEnvironment.Runtime; JniRuntime.JniValueManager valueManager = runtime.ValueManager; valueManager.WaitForGCBridgeProcessing (); AbsListView value = valueManager.GetValue<AbsListView> (__this); IListAdapter adapter = value.Adapter; return JNIEnv.ToLocalJniHandle (adapter); } catch (Exception ex) when (runtime.ExceptionShouldTransitionToJni (ex)) { jniTransition.SetPendingException (ex); return default(IntPtr); } finally { jniTransition.Dispose (); } IntPtr intPtr = default(IntPtr); return intPtr; }
|
||
foreach (var iface in info.ImplementedInterfaces) { | ||
var ifaceInfo = iface.GetTypeInfo (); | ||
marshalerAttr = ifaceInfo.GetCustomAttribute<JniValueMarshalerAttribute> (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually make sense? I'm not sure it does.
This states that an interface can contain a [JniValueMarshaler]
custom attribute on interfaces -- which is probably a mistake, as we'll see! -- but what should happen if a type implements more than one interface, each of which has a custom marshaler?
[JniValueMarshaler (...)]
public interface IX {}
[JniValueMarshaler (...)]
public interface IY {}
public class Example : JavaObject, IX, IY {
// ...
}
With this PR, we'll wind up using the custom marshaler from the first interface. Is this correct? Is this even sane?
I think we might instead want to prevent allowing interfaces to have custom marshalers, and just restrict to classes/structs/etc.
Once dotnet/java-interop#389 is merged, it should fix dotnet/java-interop#388 Example of updated marshalers: using Android.Runtime; using Java.Interop; using System; public static void n_setAdapter_Landroid_widget_ListAdapter_ (IntPtr __jnienv, IntPtr __this, IntPtr value) { JniTransition jniTransition = new JniTransition (__jnienv); JniRuntime runtime = default(JniRuntime); try { runtime = JniEnvironment.Runtime; JniRuntime.JniValueManager valueManager = runtime.ValueManager; valueManager.WaitForGCBridgeProcessing (); AbsListView value2 = valueManager.GetValue<AbsListView> (__this); IListAdapter listAdapter2 = value2.Adapter = Java.Interop.JavaConvert.FromJniHandle<IListAdapter> (value, JniHandleOwnership.DoNotTransfer); } catch (Exception ex) when (runtime.ExceptionShouldTransitionToJni (ex)) { jniTransition.SetPendingException (ex); } finally { jniTransition.Dispose (); } } and using Android.Runtime; using Java.Interop; using System; public static IntPtr n_getAdapter (IntPtr __jnienv, IntPtr __this) { JniTransition jniTransition = new JniTransition (__jnienv); JniRuntime runtime = default(JniRuntime); try { runtime = JniEnvironment.Runtime; JniRuntime.JniValueManager valueManager = runtime.ValueManager; valueManager.WaitForGCBridgeProcessing (); AbsListView value = valueManager.GetValue<AbsListView> (__this); IListAdapter adapter = value.Adapter; return JNIEnv.ToLocalJniHandle (adapter); } catch (Exception ex) when (runtime.ExceptionShouldTransitionToJni (ex)) { jniTransition.SetPendingException (ex); return default(IntPtr); } finally { jniTransition.Dispose (); } IntPtr intPtr = default(IntPtr); return intPtr; }
Before going to use the proxy object marshaler, try to check the
implemented interfaces for custom marshaler.
It will be used in XA to marshal IJavaObject based objects, which do
not implement IJavaPeerable.
That will make it possible to fix
#388