Beispiel #1
0
        /// <summary>
        /// Return the unmanaged C++ pointer from a <see cref="ICallbackable"/> instance.
        /// </summary>
        /// <typeparam name="TCallback">The type of the callback.</typeparam>
        /// <param name="callback">The callback.</param>
        /// <returns>A pointer to the unmanaged C++ object of the callback</returns>
        public static IntPtr ToCallbackPtr <TCallback>(ICallbackable callback)
            where TCallback : ICallbackable
        {
            // If callback is null, then return a null pointer
            if (callback == null)
            {
                return(IntPtr.Zero);
            }

            // If callback is CppObject
            if (callback is CppObject)
            {
                return(((CppObject)callback).NativePointer);
            }

            // Setup the shadow container in order to support multiple inheritance
            var shadowContainer = callback.Shadow as ShadowContainer;

            if (shadowContainer == null)
            {
                shadowContainer = new ShadowContainer();
                shadowContainer.Initialize(callback);
            }

            return(shadowContainer.Find(typeof(TCallback)));
        }
Beispiel #2
0
        public virtual unsafe void Initialize(ICallbackable callbackInstance)
        {
            this.Callback      = callbackInstance;
            this.NativePointer = Marshal.AllocHGlobal(IntPtr.Size * 2);
            GCHandle gcHandle = GCHandle.Alloc((object)this);

            Marshal.WriteIntPtr(this.NativePointer, this.GetVtbl.Pointer);
            ((IntPtr *)(void *)this.NativePointer)[1] = GCHandle.ToIntPtr(gcHandle);
        }
        /// <summary>
        /// Initializes the specified shadow instance from a vtbl and a callback.
        /// </summary>
        /// <param name="callbackInstance">The callback.</param>
        public virtual void Initialize(ICallbackable callbackInstance)
        {
            Callback = callbackInstance;

            Debug.Assert(Marshal.SizeOf(typeof(CppObjectNative)) == CppObjectNative.Size);

            // Allocate ptr to vtbl + ptr to callback together
            var     nativePointer = Marshal.AllocHGlobal(CppObjectNative.Size);
            ref var native        = ref *(CppObjectNative *)nativePointer;
Beispiel #4
0
        /// <summary>
        /// Initializes the specified shadow instance from a vtbl and a callback.
        /// </summary>
        /// <param name="callbackInstance">The callback.</param>
        public unsafe virtual void Initialize(ICallbackable callbackInstance)
        {
            this.Callback = callbackInstance;

            // Allocate ptr to vtbl + ptr to callback together
            NativePointer = Marshal.AllocHGlobal(IntPtr.Size * 2);

            var handle = GCHandle.Alloc(this);

            Marshal.WriteIntPtr(NativePointer, GetVtbl.Pointer);

            *((IntPtr *)NativePointer + 1) = GCHandle.ToIntPtr(handle);
        }
Beispiel #5
0
        public void Initialize(ICallbackable callbackable)
        {
            callbackable.Shadow = (IDisposable)this;
            Type        type1 = callbackable.GetType();
            List <Type> list;

            lock (ShadowContainer.typeToShadowTypes)
            {
                if (!ShadowContainer.typeToShadowTypes.TryGetValue(type1, out list))
                {
                    Type[] local_2 = type1.GetInterfaces();
                    list = new List <Type>();
                    list.AddRange((IEnumerable <Type>)local_2);
                    ShadowContainer.typeToShadowTypes.Add(type1, list);
                    foreach (Type item_1 in local_2)
                    {
                        if (ShadowAttribute.Get(item_1) == null)
                        {
                            list.Remove(item_1);
                        }
                        else
                        {
                            foreach (Type item_0 in item_1.GetInterfaces())
                            {
                                list.Remove(item_0);
                            }
                        }
                    }
                }
            }
            CppObjectShadow cppObjectShadow1 = (CppObjectShadow)null;

            foreach (Type type2 in list)
            {
                CppObjectShadow cppObjectShadow2 = (CppObjectShadow)Activator.CreateInstance(ShadowAttribute.Get(type2).Type);
                cppObjectShadow2.Initialize(callbackable);
                if (cppObjectShadow1 == null)
                {
                    cppObjectShadow1 = cppObjectShadow2;
                    this.guidToShadow.Add(ComObjectShadow.IID_IUnknown, cppObjectShadow1);
                }
                this.guidToShadow.Add(Utilities.GetGuidFromType(type2), cppObjectShadow2);
                foreach (Type type3 in type2.GetInterfaces())
                {
                    if (ShadowAttribute.Get(type3) != null)
                    {
                        this.guidToShadow.Add(Utilities.GetGuidFromType(type3), cppObjectShadow2);
                    }
                }
            }
        }
Beispiel #6
0
        protected override void Dispose(bool disposing)
        {
            if (!disposing)
            {
                return;
            }
            ICallbackable callbackable = (ICallbackable)this;

            if (callbackable.Shadow == null)
            {
                return;
            }
            callbackable.Shadow.Dispose();
            callbackable.Shadow = (IDisposable)null;
        }
        private void Dispose(bool disposing)
        {
            if (!disposing)
            {
                return;
            }
            ICallbackable callbackable = this;

            if (callbackable.Shadow == null)
            {
                return;
            }
            callbackable.Shadow.Dispose();
            callbackable.Shadow = null;
        }
Beispiel #8
0
 public void Initialize(ICallbackable callbackable)
 {
     callbackable.Shadow = (IDisposable) this;
       Type type1 = callbackable.GetType();
       List<Type> list;
       lock (ShadowContainer.typeToShadowTypes)
       {
     if (!ShadowContainer.typeToShadowTypes.TryGetValue(type1, out list))
     {
       Type[] local_2 = type1.GetInterfaces();
       list = new List<Type>();
       list.AddRange((IEnumerable<Type>) local_2);
       ShadowContainer.typeToShadowTypes.Add(type1, list);
       foreach (Type item_1 in local_2)
       {
     if (ShadowAttribute.Get(item_1) == null)
     {
       list.Remove(item_1);
     }
     else
     {
       foreach (Type item_0 in item_1.GetInterfaces())
         list.Remove(item_0);
     }
       }
     }
       }
       CppObjectShadow cppObjectShadow1 = (CppObjectShadow) null;
       foreach (Type type2 in list)
       {
     CppObjectShadow cppObjectShadow2 = (CppObjectShadow) Activator.CreateInstance(ShadowAttribute.Get(type2).Type);
     cppObjectShadow2.Initialize(callbackable);
     if (cppObjectShadow1 == null)
     {
       cppObjectShadow1 = cppObjectShadow2;
       this.guidToShadow.Add(ComObjectShadow.IID_IUnknown, cppObjectShadow1);
     }
     this.guidToShadow.Add(Utilities.GetGuidFromType(type2), cppObjectShadow2);
     foreach (Type type3 in type2.GetInterfaces())
     {
       if (ShadowAttribute.Get(type3) != null)
     this.guidToShadow.Add(Utilities.GetGuidFromType(type3), cppObjectShadow2);
     }
       }
 }
Beispiel #9
0
        public static IntPtr ToIntPtr <TCallback>(ICallbackable callback) where TCallback : ICallbackable
        {
            if (callback == null)
            {
                return(IntPtr.Zero);
            }
            if (callback is CppObject)
            {
                return(((CppObject)callback).NativePointer);
            }
            ShadowContainer shadowContainer = callback.Shadow as ShadowContainer;

            if (shadowContainer == null)
            {
                shadowContainer = new ShadowContainer();
                shadowContainer.Initialize(callback);
            }
            return(shadowContainer.Find(typeof(TCallback)));
        }
Beispiel #10
0
        public void Initialize(ICallbackable callbackable)
        {
            callbackable.Shadow = this;

            var         type = callbackable.GetType();
            List <Type> slimInterfaces;

            // Cache reflection on COM interface inheritance
            lock (typeToShadowTypes)
            {
                if (!typeToShadowTypes.TryGetValue(type, out slimInterfaces))
                {
#if BEFORE_NET45
                    var interfaces = type.GetTypeInfo().GetInterfaces();
#else
                    var interfaces = type.GetTypeInfo().ImplementedInterfaces;
#endif
                    slimInterfaces = new List <Type>();
                    slimInterfaces.AddRange(interfaces);
                    typeToShadowTypes.Add(type, slimInterfaces);

                    // First pass to identify most detailed interfaces
                    foreach (var item in interfaces)
                    {
                        // Only process interfaces that are using shadow
                        var shadowAttribute = ShadowAttribute.Get(item);
                        if (shadowAttribute == null)
                        {
                            slimInterfaces.Remove(item);
                            continue;
                        }

                        // Keep only final interfaces and not intermediate.
#if BEFORE_NET45
                        var inheritList = item.GetTypeInfo().GetInterfaces();
#else
                        var inheritList = item.GetTypeInfo().ImplementedInterfaces;
#endif
                        foreach (var inheritInterface in inheritList)
                        {
                            slimInterfaces.Remove(inheritInterface);
                        }
                    }
                }
            }

            CppObjectShadow iunknownShadow = null;

            // Second pass to instantiate shadow
            foreach (var item in slimInterfaces)
            {
                // Only process interfaces that are using shadow
                var shadowAttribute = ShadowAttribute.Get(item);

                // Initialize the shadow with the callback
                var shadow = (CppObjectShadow)Activator.CreateInstance(shadowAttribute.Type);
                shadow.Initialize(callbackable);

                // Take the first shadow as the main IUnknown
                if (iunknownShadow == null)
                {
                    iunknownShadow = shadow;
                    // Add IUnknown as a supported interface
                    guidToShadow.Add(ComObjectShadow.IID_IUnknown, iunknownShadow);
                }

                guidToShadow.Add(Utilities.GetGuidFromType(item), shadow);

                // Associate also inherited interface to this shadow
#if BEFORE_NET45
                var inheritList = item.GetTypeInfo().GetInterfaces();
#else
                var inheritList = item.GetTypeInfo().ImplementedInterfaces;
#endif
                foreach (var inheritInterface in inheritList)
                {
                    var inheritShadowAttribute = ShadowAttribute.Get(inheritInterface);
                    if (inheritShadowAttribute == null)
                    {
                        continue;
                    }

                    // Use same shadow as derived
                    guidToShadow.Add(Utilities.GetGuidFromType(inheritInterface), shadow);
                }
            }

            // Precalculate the list of GUID without IUnknown and IInspectable
            // Used for WinRT
            int countGuids = 0;
            foreach (var guidKey in guidToShadow.Keys)
            {
                if (guidKey != Utilities.GetGuidFromType(typeof(IInspectable)) && guidKey != Utilities.GetGuidFromType(typeof(IUnknown)))
                {
                    countGuids++;
                }
            }

            guidPtr = Marshal.AllocHGlobal(Utilities.SizeOf <Guid>() * countGuids);
            Guids   = new IntPtr[countGuids];
            int i = 0;
            unsafe
            {
                var pGuid = (Guid *)guidPtr;
                foreach (var guidKey in guidToShadow.Keys)
                {
                    if (guidKey == Utilities.GetGuidFromType(typeof(IInspectable)) || guidKey == Utilities.GetGuidFromType(typeof(IUnknown)))
                    {
                        continue;
                    }

                    pGuid[i] = guidKey;
                    // Store the pointer
                    Guids[i] = new IntPtr(pGuid + i);
                    i++;
                }
            }
        }
Beispiel #11
0
        public void Initialize(ICallbackable callbackable)
        {
            callbackable.Shadow = this;

            var type = callbackable.GetType();
            List<Type> slimInterfaces;

            // Cache reflection on COM interface inheritance
            lock (typeToShadowTypes)
            {
                if (!typeToShadowTypes.TryGetValue(type, out slimInterfaces))
                {
#if W8CORE
                    var interfaces = type.GetTypeInfo().ImplementedInterfaces;
#else
                    var interfaces = type.GetInterfaces();
#endif
                    slimInterfaces = new List<Type>();
                    slimInterfaces.AddRange(interfaces);
                    typeToShadowTypes.Add(type, slimInterfaces);

                    // First pass to identify most detailled interfaces
                    foreach (var item in interfaces)
                    {
                        // Only process interfaces that are using shadow
                        var shadowAttribute = ShadowAttribute.Get(item);
                        if (shadowAttribute == null)
                        {
                            slimInterfaces.Remove(item);
                            continue;
                        }

                        // Keep only final interfaces and not intermediate.
#if W8CORE
                        var inheritList = item.GetTypeInfo().ImplementedInterfaces;
#else
                        var inheritList = item.GetInterfaces();
#endif
                        foreach (var inheritInterface in inheritList)
                        {
                            slimInterfaces.Remove(inheritInterface);
                        }
                    }
                }
            }

            CppObjectShadow iunknownShadow = null;

            // Second pass to instantiate shadow
            foreach (var item in slimInterfaces)
            {
                // Only process interfaces that are using shadow
                var shadowAttribute = ShadowAttribute.Get(item);

                // Initialize the shadow with the callback
                var shadow = (CppObjectShadow)Activator.CreateInstance(shadowAttribute.Type);
                shadow.Initialize(callbackable);

                // Take the first shadow as the main IUnknown
                if (iunknownShadow == null)
                {
                    iunknownShadow = shadow;
                    // Add IUnknown as a supported interface
                    guidToShadow.Add(ComObjectShadow.IID_IUnknown, iunknownShadow);
                }

                guidToShadow.Add(Utilities.GetGuidFromType(item), shadow);

                // Associate also inherited interface to this shadow
#if W8CORE
                var inheritList = item.GetTypeInfo().ImplementedInterfaces;
#else
                var inheritList = item.GetInterfaces();
#endif
                foreach (var inheritInterface in inheritList)
                {
                    var inheritShadowAttribute = ShadowAttribute.Get(inheritInterface);
                    if (inheritShadowAttribute == null)
                        continue;

                    // Use same shadow as derived
                    guidToShadow.Add(Utilities.GetGuidFromType(inheritInterface), shadow);
                }
            }

#if W8CORE
            // Precalculate the list of GUID without IUnknown and IInspectable
            // Used for WinRT 
            int countGuids = 0;
            foreach (var guidKey in guidToShadow.Keys)
            {
                if (guidKey != Utilities.GetGuidFromType(typeof(IInspectable)) && guidKey != Utilities.GetGuidFromType(typeof(IUnknown)))
                    countGuids++;
            }

            guidPtr = Marshal.AllocHGlobal(Utilities.SizeOf<Guid>() * countGuids);
            Guids = new IntPtr[countGuids];
            int i = 0;
            unsafe
            {
                var pGuid = (Guid*) guidPtr;
                foreach (var guidKey in guidToShadow.Keys)
                {
                    if (guidKey == Utilities.GetGuidFromType(typeof(IInspectable)) || guidKey == Utilities.GetGuidFromType(typeof(IUnknown)))
                        continue;

                    pGuid[i] = guidKey;
                    // Store the pointer
                    Guids[i] = new IntPtr(pGuid + i);
                    i++;
                }
            }
#endif
        }
 /// <summary>
 /// Return the unmanaged C++ pointer from a <see cref="SharpGen.Runtime.ICallbackable"/> instance.
 /// </summary>
 /// <typeparam name="TCallback">The type of the callback.</typeparam>
 /// <param name="callback">The callback.</param>
 /// <returns>A pointer to the unmanaged C++ object of the callback</returns>
 public static IntPtr ToCallbackPtr <TCallback>(ICallbackable callback) where TCallback : ICallbackable =>
 callback switch
 {
     null => IntPtr.Zero,
        internal ShadowContainer(ICallbackable callbackable)
        {
            var type = callbackable.GetType();

            var guidList = new List <Guid>();

            // Associate all shadows with their interfaces.
            foreach (var item in GetUninheritedShadowedInterfaces(type))
            {
                var shadowAttribute = ShadowAttribute.Get(item);

                // Initialize the shadow with the callback
                var shadow = (CppObjectShadow)Activator.CreateInstance(shadowAttribute.Type);
                shadow.Initialize(callbackable);

                guidToShadow.Add(item.GetTypeInfo().GUID, shadow);
                if (item.GetTypeInfo().GetCustomAttribute <ExcludeFromTypeListAttribute>() != null)
                {
                    guidList.Add(item.GetTypeInfo().GUID);
                }

                // Associate also inherited interface to this shadow
                var inheritList = item.GetTypeInfo().ImplementedInterfaces;

                foreach (var inheritInterface in inheritList)
                {
                    // If there isn't a Shadow attribute then this isn't a native interface.
                    var inheritShadowAttribute = ShadowAttribute.Get(inheritInterface);
                    if (inheritShadowAttribute == null)
                    {
                        continue;
                    }

                    // If we have the same GUID as an already added interface,
                    // then there's already an accurate shadow for it, so we have nothing to do.
                    if (guidToShadow.ContainsKey(inheritInterface.GetTypeInfo().GUID))
                    {
                        continue;
                    }

                    // Use same shadow as derived
                    guidToShadow.Add(inheritInterface.GetTypeInfo().GUID, shadow);
                    if (inheritInterface.GetTypeInfo().GetCustomAttribute <ExcludeFromTypeListAttribute>() != null)
                    {
                        guidList.Add(inheritInterface.GetTypeInfo().GUID);
                    }
                }
            }

            var guidCount = guidList.Count;

            Guids = new IntPtr[guidCount];

            guidPtr = Marshal.AllocHGlobal(Unsafe.SizeOf <Guid>() * guidCount);

            unsafe
            {
                var i     = 0;
                var pGuid = (Guid *)guidPtr;
                foreach (var guidKey in guidList)
                {
                    pGuid[i] = guidKey;
                    // Store the pointer
                    Guids[i] = new IntPtr(pGuid + i);
                    i++;
                }
            }
        }