示例#1
0
        /// <summary>
        /// Get the currently registered managed object or creates a new managed object and registers it.
        /// </summary>
        /// <param name="impl">The <see cref="ComWrappers" /> implementation to use when creating the managed object.</param>
        /// <param name="externalComObject">Object to import for usage into the .NET runtime.</param>
        /// <param name="innerMaybe">The inner instance if aggregation is involved</param>
        /// <param name="flags">Flags used to describe the external object.</param>
        /// <param name="wrapperMaybe">The <see cref="object"/> to be used as the wrapper for the external object.</param>
        /// <param name="retValue">The managed object associated with the supplied external COM object or <c>null</c> if it could not be created.</param>
        /// <returns>Returns <c>true</c> if a managed object could be retrieved/created, <c>false</c> otherwise</returns>
        /// <remarks>
        /// If <paramref name="impl" /> is <c>null</c>, the global instance (if registered) will be used.
        /// </remarks>
        private static bool TryGetOrCreateObjectForComInstanceInternal(
            ComWrappers impl,
            IntPtr externalComObject,
            IntPtr innerMaybe,
            CreateObjectFlags flags,
            object?wrapperMaybe,
            out object?retValue
            )
        {
            if (externalComObject == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(externalComObject));
            }

            // If the inner is supplied the Aggregation flag should be set.
            if (innerMaybe != IntPtr.Zero && !flags.HasFlag(CreateObjectFlags.Aggregation))
            {
                throw new InvalidOperationException(
                          SR.InvalidOperation_SuppliedInnerMustBeMarkedAggregation
                          );
            }

            object?wrapperMaybeLocal = wrapperMaybe;

            retValue = null;
            return(TryGetOrCreateObjectForComInstanceInternal(
                       ObjectHandleOnStack.Create(ref impl),
                       impl.id,
                       externalComObject,
                       innerMaybe,
                       flags,
                       ObjectHandleOnStack.Create(ref wrapperMaybeLocal),
                       ObjectHandleOnStack.Create(ref retValue)
                       ));
        }
        protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
        {
            // Assert use of the UniqueInstance flag since the returned Native Object Wrapper always
            // supports IDisposable and its Dispose will always release and suppress finalization.
            // If the wrapper doesn't always support IDisposable the assert can be relaxed.
            Debug.Assert(flags.HasFlag(CreateObjectFlags.UniqueInstance));

            // Throw an exception if the type is not supported by the implementation.
            // Null can be returned as well, but an ArgumentNullException will be thrown for
            // the consumer of this ComWrappers instance.
            return(SymNgenWriterWrapper.CreateIfSupported(externalComObject) ?? throw new NotSupportedException());
        }