Ejemplo n.º 1
0
 protected GType LookupGType()
 {
     if (Handle != IntPtr.Zero)
     {
         GTypeInstance obj   = (GTypeInstance)Marshal.PtrToStructure(Handle, typeof(GTypeInstance));
         GTypeClass    klass = (GTypeClass)Marshal.PtrToStructure(obj.g_class, typeof(GTypeClass));
         return(new GLib.GType(klass.gtype));
     }
     else
     {
         return(LookupGType(GetType()));
     }
 }
Ejemplo n.º 2
0
        // Wraps a pointer to a GObject with a native wrapper type
        // NOTE: generic type T is the type we want to cast as, NOT the
        // actual type of the object.
        public static T WrapPointerAs <T>(IntPtr ptr, bool owned)
            where T : GLib.Object, new()
        {
            // Sanity Check
            if (ptr == IntPtr.Zero)
            {
                return(null);
            }

            // 1. Check if we already have a wrapper for this instance
            //    We should always have an existing wrapper for subclasses
            //    because the object must never outlive the wrapper.
            //
            // NOTE: If we for some reason need to create wrappers for user-defined
            // types in the future, it may be worth adding a GObjectArgs type to pass
            // to constructors to inhibit construction.
            GLib.Object wrapper;
            if (wrappers.TryGetValue(ptr, out wrapper))
            {
                if (owned && !wrapper.isOwned)
                {
                    wrapper.Take();
                }

                // Ensure it is possible to return the wrapper
                // as the requested type.
                bool isEqual    = wrapper.GetType() == typeof(T);
                bool isSubclass = wrapper.GetType().IsSubclassOf(typeof(T));

                if (!(isEqual || isSubclass))
                {
                    throw new InvalidCastException($"Cannot get pointer as {typeof(T).FullName}");
                }

                return((T)wrapper);
            }

            // 2. No wrapper exists for this pointer. We assume that the pointer cannot be a
            //    user created managed subclass (this will always match the lifetime of the native
            //    object), so we initialise a new wrapper with the type of the pointer.
            GTypeInstance obj   = (GTypeInstance)Marshal.PtrToStructure(ptr, typeof(GTypeInstance));
            GTypeClass    klass = (GTypeClass)Marshal.PtrToStructure(obj.g_class, typeof(GTypeClass));

            System.Type realType = (Type) new GLib.GType(klass.gtype);

            // We cannot wrap a subclass
            // The subclass wrapper must always outlive the GObject and we
            // enforce this with ToggleRefs
            // TODO: Use ToggleRefs
            if (IsManaged(typeof(T)))
            {
                throw new Exception("We cannot wrap a managed subclass. Something has gone very wrong");
            }

            // 3. Create the wrapper type. The wrapper uses lazy initialisation to allow us to
            //    alternatively initialise it as a wrapper, so we call InitWrapper before Handle
            //    can be used.
            T ret = (T)Activator.CreateInstance(realType, null);

            ret.InitWrapper(ptr, owned);

            return(ret);
        }