예제 #1
0
        public static object FromJavaObject(IJavaObject value, Type targetType = null)
        {
            if (value == null)
            {
                return(null);
            }

            if (targetType != null && typeof(IJavaObject).IsAssignableFrom(targetType))
            {
                return(JavaObjectExtensions.JavaCast(value, targetType));
            }

            var o = value as JavaObject;

            if (o != null)
            {
                if (targetType == null)
                {
                    return(o.Instance);
                }
                return(Convert.ChangeType(o.Instance, targetType));
            }

            if (targetType == null || targetType.IsAssignableFrom(value.GetType()))
            {
                return(value);
            }

            IntPtr lrefValue = JNIEnv.ToLocalJniHandle(value);

            if (lrefValue == IntPtr.Zero)
            {
                return(null);
            }
            Func <IntPtr, JniHandleOwnership, object> converter = GetJniHandleConverter(targetType);

            if (converter != null)
            {
                return(converter(lrefValue, JniHandleOwnership.TransferLocalRef));
            }
            JNIEnv.DeleteLocalRef(lrefValue);
            return(Convert.ChangeType(value, targetType));
        }
예제 #2
0
        internal static IJavaPeerable CreateInstance(IntPtr handle, JniHandleOwnership transfer, Type targetType)
        {
            Type   type       = null;
            IntPtr class_ptr  = JNIEnv.GetObjectClass(handle);
            string class_name = GetClassName(class_ptr);

            lock (TypeManagerMapDictionaries.AccessLock) {
                while (class_ptr != IntPtr.Zero && !TypeManagerMapDictionaries.JniToManaged.TryGetValue(class_name, out type))
                {
                    type = GetJavaToManagedType(class_name);
                    if (type != null)
                    {
                        TypeManagerMapDictionaries.JniToManaged.Add(class_name, type);
                        break;
                    }

                    IntPtr super_class_ptr = JNIEnv.GetSuperclass(class_ptr);
                    JNIEnv.DeleteLocalRef(class_ptr);
                    class_ptr  = super_class_ptr;
                    class_name = GetClassName(class_ptr);
                }
            }

            JNIEnv.DeleteLocalRef(class_ptr);

            if (type == null)
            {
                JNIEnv.DeleteRef(handle, transfer);
                throw new NotSupportedException(
                          string.Format("Internal error finding wrapper class for '{0}'. (Where is the Java.Lang.Object wrapper?!)",
                                        JNIEnv.GetClassNameFromInstance(handle)),
                          CreateJavaLocationException());
            }

            if (targetType != null && !targetType.IsAssignableFrom(type))
            {
                type = targetType;
            }

            if (type.IsInterface || type.IsAbstract)
            {
                var invokerType = JavaObjectExtensions.GetHelperType(type, "Invoker");
                if (invokerType == null)
                {
                    throw new NotSupportedException("Unable to find Invoker for type '" + type.FullName + "'. Was it linked away?",
                                                    CreateJavaLocationException());
                }
                type = invokerType;
            }


            IJavaPeerable result = null;

            try {
                result = (IJavaPeerable)CreateProxy(type, handle, transfer);
                if (Runtime.IsGCUserPeer(result.PeerReference.Handle))
                {
                    result.SetJniManagedPeerState(JniManagedPeerStates.Replaceable);
                }
            } catch (MissingMethodException e) {
                var key_handle = JNIEnv.IdentityHash(handle);
                JNIEnv.DeleteRef(handle, transfer);
                throw new NotSupportedException(
                          string.Format("Unable to activate instance of type {0} from native handle 0x{1} (key_handle 0x{2}).",
                                        type, handle.ToString("x"), key_handle.ToString("x")),
                          e);
            }
            return(result);
        }