【问题标题】:How to cast C# interface to Java.Lang.Object?如何将 C# 接口转换为 Java.Lang.Object?
【发布时间】:2017-11-10 07:16:52
【问题描述】:

目前,我正在 Xamarin 中研究 IEGL10。我已经实现了ISurfaceHolderCallbackSurfaceCreated(ISurfaceHolder holder) 我必须调用这样的方法。

 public void SurfaceCreated(ISurfaceHolder holder)
 {
   mEglSurface = mEgl.EglCreateWindowSurface(mEglDisplay, mEglConfig,
            holder, null);
 }

问题是,持有者是一个C#接口,而EglCreateWindowSurface需要Java.Lang.Object。那么我该如何进行铸造。如果我直接投像(Java.Lang.Object)holder这样的持有人。它正在抛出无效的强制转换异常。 请帮助我真的被困在这里的人。

【问题讨论】:

  • 我对 Xamarin 不够熟悉,无法回答这个问题。但是,如果您所指的 Java.Lang.Object 类型是 C# 类型,并且您无法在此处更改实现 ISurfaceHolder 的类的类型层次结构,那么您将不得不包装 holder 对象在不同的类型中继承Java.Lang.Object,实现ISurfaceHolder,并将所有接口成员委托给原始holder对象。
  • SurfaceCreated(ISurfaceHolder holder) 是 ISurfaceHolderCallback 的重写方法。所以我不能包装持有人对象。
  • “所以我不能包装持有者对象”——对我来说似乎是不合理的。你的第一句话和第二句话有什么关系?您的帖子暗示 编写了 SurfaceCreated() 方法并正在调用 EglCreateWindowSurface() 方法。因此,您可以在将 holder 对象传递给 EglCreateWindowSurface() 方法之前访问它,并且可以将其包装在那里。底线:不知何故,你必须想出一个 Java.Lang.Object 对象才能传递,如果 holder 不能成为那样,你必须传递其他东西。

标签: c# android xamarin casting


【解决方案1】:

如何将 C# 接口转换为 Java.Lang.Object?

MonoDroid为此目的集成了扩展:

Java.Lang.Object holder_object = holder.JavaCast<Java.Lang.Object>(); 

EGLSurface mEglSurface = mEgl.EglCreateWindowSurface(mEglDisplay, mEglConfig, holder_object, null);

你可以看到文件:

public static class Extensions
{
    //
    // Summary:
    //     /// Performs an Android runtime-checked type conversion. ///
    //
    // Parameters:
    //   instance:
    //     /// An Android.Runtime.IJavaObject instance to convert /// to a TResult instance.
    //     ///
    //
    // Type parameters:
    //   TResult:
    //     /// The type to convert instance to. /// TResult must implement the /// Android.Runtime.IJavaObject
    //     interface. ///
    //
    // Returns:
    //     /// A TResult representation for /// instance. ///
    //
    // Exceptions:
    //   T:System.ArgumentException:
    //     ///
    //     /// The JNI class for TResult cannot be found. ///
    //     ///
    //     -or-
    //     ///
    //     /// The proxy class for TResult is /// abstract, and the non-abstract Proxy can't
    //     be found. ///
    //     ///
    //
    //   T:System.InvalidCastException:
    //     /// The Anrdroid object instance instance.Handle /// cannot be converted to the
    //     Android type corresponding to /// TResult. ///
    //
    //   T:System.NotSupportedException:
    //     /// An unknown error occurred. ///
    //
    // Remarks:
    //     /// /// This is a hack, but a currently necessary one. /// ///
    //     /// Most of the Android types are staticly generated /// wrappers over a description
    //     of the underlying Android types. This /// intermediate description does not expose
    //     implementation details, /// which sometimes must be relied upon. ///
    //     ///
    //     /// For example, consider the /// Javax.Microedition.Khronos.Egl.EGLContext.EGL
    //     /// property, which returns an instance of the /// Javax.Microedition.Khronos.Egl.IEGL
    //     /// interface. This interface is useless, containing no members to /// invoke
    //     or use. The developer is instead expected to convert this /// instance to an
    //     interface which contains actual operations, such as /// the Javax.Microedition.Khronos.Egl.IEGL10
    //     interface. /// Unfortunately, the MonoDroid-generated wrappers do not know this,
    //     /// nor can they (the EGL10 implementation may be removed in a /// future Android
    //     version). The result is that if developers attempt /// to cast within managed
    //     code, the result will be a /// System.InvalidCastException: ///
    //     /// EGL10 egl10 = (EGL10) EGLContext.EGL; // throws ///
    //     /// The JavaCast() method allows performing such type conversions /// while bypassing
    //     the managed type system and instead relying upon /// the Android runtime system
    //     to perform the type checking. This /// allows: ///
    //     /// EGL10 egl10 = EGLContext.EGL.JavaCast<EGL10>(); // good ///
    public static TResult JavaCast<TResult>(this IJavaObject instance) where TResult : class, IJavaObject;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    相关资源
    最近更新 更多