示例#1
0
        /// <summary>
        /// Gets the GluonObject representation of the underlying pointer.
        /// If GluonObject already existed,
        /// calls Marshal.Release() on the native pointer before returning the existing object.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="native"></param>
        /// <returns></returns>
        public static T Of <T>(IntPtr native) where T : GluonObject
        {
            if (native == IntPtr.Zero)
            {
                return(null);
            }

            lock (All)
            {
                WeakReference rret;
                GluonObject   ret;
                if (All.TryGetValue(native, out rret) || All.TryGetValue(GetRootPointer(native), out rret))
                {
                    ret = rret.Target as GluonObject;
                    Marshal.Release(native);
                }
                else
                {
                    var id = VTObject.Id;

                    IntPtr ioPtr;
                    Marshal.QueryInterface(native, ref id, out ioPtr);

                    if (ioPtr == IntPtr.Zero)
                    {
                        return(null);
                    }

                    VTObject io = VTUnknown.GetVTable <VTObject>(ioPtr);
                    io.GetTypeId(ioPtr, ref id);
                    Marshal.Release(ioPtr);
                    Func <IntPtr, GluonObject> factory;
                    if (!WrapperFactories.TryGetValue(id, out factory))
                    {
                        return(null);
                    }

                    ret = factory(ioPtr);
                    if (ret == null)
                    {
                        throw new Exception("Failed to construct wrapper for native type " + native.GetType().ToString());
                    }
                }

                return(ret as T);
            }
        }
示例#2
0
        private static IntPtr GetRootPointer(IntPtr native)
        {
            var    id = VTObject.Id;
            IntPtr ptr;

            Marshal.QueryInterface(native, ref id, out ptr);
            if (ptr == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }
            Marshal.Release(ptr);

            VTObject io = VTUnknown.GetVTable <VTObject>(ptr);

            io.GetTypeId(ptr, ref id);
            return(io.CastTo(ptr, ref id));
        }