Example #1
0
        internal static unsafe IntPtr ObjectToComInterfaceInternal(Object obj, RuntimeTypeHandle typeHnd)
        {
            if (obj == null)
            {
                return(default(IntPtr));
            }

#if ENABLE_WINRT
            //
            // Try boxing if this is a WinRT object
            //
            if (typeHnd.Equals(InternalTypes.IInspectable))
            {
                object unboxed = McgMarshal.BoxIfBoxable(obj);

                //
                // Marshal ReferenceImpl<T> to WinRT as IInspectable
                //
                if (unboxed != null)
                {
                    obj = unboxed;
                }
                else
                {
                    //
                    // Anything that can be casted to object[] will be boxed as object[]
                    //
                    object[] objArray = obj as object[];
                    if (objArray != null)
                    {
                        unboxed = McgMarshal.BoxIfBoxable(obj, typeof(object[]).TypeHandle);
                        if (unboxed != null)
                        {
                            obj = unboxed;
                        }
                    }
                }
            }
#endif //ENABLE_WINRT

            //
            // If this is a RCW, and the RCW is not a base class (managed class deriving from RCW class),
            // QI on the RCW
            //
            __ComObject comObject = obj as __ComObject;

            if (comObject != null && !comObject.ExtendsComObject)
            {
                IntPtr pComPtr = comObject.QueryInterface_NoAddRef_Internal(typeHnd, /* cacheOnly= */ false, /* throwOnQueryInterfaceFailure= */ false);
                if (pComPtr == default(IntPtr))
                {
                    return(default(IntPtr));
                }

                McgMarshal.ComAddRef(pComPtr);
                GC.KeepAlive(comObject); // make sure we don't collect the object before adding a refcount.

                return(pComPtr);
            }

            //
            // Otherwise, go down the CCW code path
            //
            return(ManagedObjectToComInterface(obj, typeHnd));
        }