Example #1
0
        private static __ComObject CreateComObjectInternal(RuntimeTypeHandle classType, IntPtr pComItf)
        {
            Debug.Assert(!classType.IsNull());

            if (classType.Equals(McgModule.s_DependencyReductionTypeRemovedTypeHandle))
            {
                // We should filter out the strongly typed RCW in TryGetClassInfoFromName step
#if !RHTESTCL
                Environment.FailFast(McgTypeHelpers.GetDiagnosticMessageForMissingType(classType));
#else
                Environment.FailFast("We should never see strongly typed RCW discarded here");
#endif
            }

            //Note that this doesn't run the constructor in RH but probably do in your reflection based implementation.
            //If this were a real RCW, you would actually 'new' the RCW which is wrong. Fortunately in CoreCLR we don't have
            //this scenario so we are OK, but we should figure out a way to fix this by having a runtime API.
            object newClass = InteropExtensions.RuntimeNewObject(classType);

            Debug.Assert(newClass is __ComObject);

            __ComObject newObj = InteropExtensions.UncheckedCast <__ComObject>(newClass);

            IntPtr pfnCtor = AddrOfIntrinsics.AddrOf <AddrOfIntrinsics.AddrOfAttachingCtor>(__ComObject.AttachingCtor);
            CalliIntrinsics.Call <int>(pfnCtor, newObj, pComItf, classType);

            return(newObj);
        }
Example #2
0
        /// <summary>
        /// Retrieve the corresponding P/invoke instance from the stub
        /// </summary>
        public static Delegate GetPInvokeDelegateForStub(IntPtr pStub, RuntimeTypeHandle delegateType)
        {
            if (pStub == IntPtr.Zero)
            {
                return(null);
            }
            //
            // First try to see if this is one of the thunks we've allocated when we marshal a managed
            // delegate to native code
            // s_thunkPoolHeap will be null if there isn't any managed delegate to native
            //
            IntPtr pContext;
            IntPtr pTarget;

            if (s_thunkPoolHeap != null && RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, pStub, out pContext, out pTarget))
            {
                GCHandle handle;
                unsafe
                {
                    // Pull out Handle from context
                    handle = ((ThunkContextData *)pContext)->Handle;
                }
                Delegate target = InteropExtensions.UncheckedCast <Delegate>(handle.Target);

                //
                // The delegate might already been garbage collected
                // User should use GC.KeepAlive or whatever ways necessary to keep the delegate alive
                // until they are done with the native function pointer
                //
                if (target == null)
                {
                    Environment.FailFast(SR.Delegate_GarbageCollected);
                }

                return(target);
            }

            //
            // Otherwise, the stub must be a pure native function pointer
            // We need to create the delegate that points to the invoke method of a
            // NativeFunctionPointerWrapper derived class
            //
            McgPInvokeDelegateData pInvokeDelegateData;

            if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(delegateType, out pInvokeDelegateData))
            {
                return(null);
            }
            return(CalliIntrinsics.Call <Delegate>(
                       pInvokeDelegateData.ForwardDelegateCreationStub,
                       pStub
                       ));
        }
Example #3
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            // Boxed struct start at offset 1 (EEType* at offset 0) while class start at offset 0
            int offset = structureTypeHandle.IsValueType() ? 1 : 0;

            IntPtr unmarshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeAugments.InteropCallbacks.GetStructUnmarshalStub(structureTypeHandle);
            }

            if (unmarshalStub != IntPtr.Zero)
            {
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    CalliIntrinsics.Call <int>(
                        unmarshalStub,
                        (void *)ptr,                                        // unsafe (no need to adjust as it is always struct)
                        ((void *)((IntPtr *)unboxedStructPtr + offset))     // safe (need to adjust offset as it could be class)
                        );
                });
            }
            else
            {
                int structSize = Marshal.SizeOf(structure);
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    InteropExtensions.Memcpy(
                        (IntPtr)((IntPtr *)unboxedStructPtr + offset),      // safe (need to adjust offset as it could be class)
                        ptr,                                                // unsafe (no need to adjust as it is always struct)
                        structSize
                        );
                });
            }
        }
Example #4
0
        public static unsafe void DestroyStructure(IntPtr ptr, Type structuretype)
        {
            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (structuretype == null)
            {
                throw new ArgumentNullException(nameof(structuretype));
            }

            RuntimeTypeHandle structureTypeHandle = structuretype.TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(SR.Argument_NeedNonGenericType, "t");
            }

            if (structureTypeHandle.IsEnum() ||
                structureTypeHandle.IsInterface() ||
                InteropExtensions.AreTypesAssignable(typeof(Delegate).TypeHandle, structureTypeHandle))
            {
                throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structureTypeHandle.LastResortToString));
            }

            if (structureTypeHandle.IsBlittable())
            {
                // ok to call with blittable structure, but no work to do in this case.
                return;
            }

            IntPtr destroyStructureStub = RuntimeAugments.InteropCallbacks.GetDestroyStructureStub(structureTypeHandle, out bool hasInvalidLayout);

            if (hasInvalidLayout)
            {
                throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structureTypeHandle.LastResortToString));
            }
            // DestroyStructureStub == IntPtr.Zero means its fields don't need to be destroied
            if (destroyStructureStub != IntPtr.Zero)
            {
                CalliIntrinsics.Call <int>(
                    destroyStructureStub,
                    (void *)ptr                                     // unsafe (no need to adjust as it is always struct)
                    );
            }
        }
Example #5
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            IntPtr unmarshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeAugments.InteropCallbacks.GetStructUnmarshalStub(structureTypeHandle);
            }

            if (unmarshalStub != IntPtr.Zero)
            {
                if (structureTypeHandle.IsValueType())
                {
                    CalliIntrinsics.Call(
                        unmarshalStub,
                        ref *(byte *)ptr,
                        ref structure.GetRawData());
                }
                else
                {
                    CalliIntrinsics.Call(
                        unmarshalStub,
                        ref *(byte *)ptr,
                        structure);
                }
            }
            else
            {
                nuint size = (nuint)RuntimeAugments.InteropCallbacks.GetStructUnsafeStructSize(structureTypeHandle);
                fixed(byte *pDest = &structure.GetRawData())
                {
                    Buffer.Memmove(pDest, (byte *)ptr, size);
                }
            }
        }
Example #6
0
        public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)
        {
            if (structure == null)
            {
                throw new ArgumentNullException(nameof(structure));
            }

            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (fDeleteOld)
            {
                DestroyStructure(ptr, structure.GetType());
            }

            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(nameof(structure), SR.Argument_NeedNonGenericObject);
            }

            IntPtr marshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructMarshalStub(structureTypeHandle, out marshalStub))
                {
                    marshalStub = IntPtr.Zero;
                }
            }
            else
            {
                marshalStub = RuntimeAugments.InteropCallbacks.GetStructMarshalStub(structureTypeHandle);
            }

            if (marshalStub != IntPtr.Zero)
            {
                if (structureTypeHandle.IsValueType())
                {
                    CalliIntrinsics.Call(marshalStub,
                                         ref structure.GetRawData(),
                                         ref *(byte *)ptr);
                }
                else
                {
                    CalliIntrinsics.Call(marshalStub,
                                         structure,
                                         ref *(byte *)ptr);
                }
            }
            else
            {
                nuint size = (nuint)RuntimeAugments.InteropCallbacks.GetStructUnsafeStructSize(structureTypeHandle);
                fixed(byte *pSrc = &structure.GetRawData())
                {
                    Buffer.Memmove((byte *)ptr, pSrc, size);
                }
            }
        }
Example #7
0
        public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)
        {
            if (structure == null)
            {
                throw new ArgumentNullException(nameof(structure));
            }

            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (fDeleteOld)
            {
                DestroyStructure(ptr, structure.GetType());
            }

            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(nameof(structure), SR.Argument_NeedNonGenericObject);
            }

            // Boxed struct start at offset 1 (EEType* at offset 0) while class start at offset 0
            int offset = structureTypeHandle.IsValueType() ? 1 : 0;

            IntPtr marshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructMarshalStub(structureTypeHandle, out marshalStub))
                {
                    marshalStub = IntPtr.Zero;
                }
            }
            else
            {
                marshalStub = RuntimeAugments.InteropCallbacks.GetStructMarshalStub(structureTypeHandle);
            }

            if (marshalStub != IntPtr.Zero)
            {
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    CalliIntrinsics.Call <int>(
                        marshalStub,
                        ((void *)((IntPtr *)unboxedStructPtr + offset)),    // safe (need to adjust offset as it could be class)
                        (void *)ptr                                         // unsafe (no need to adjust as it is always struct)
                        );
                });
            }
            else
            {
                int structSize = Marshal.SizeOf(structure);
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    InteropExtensions.Memcpy(
                        ptr,                                                // unsafe (no need to adjust as it is always struct)
                        (IntPtr)((IntPtr *)unboxedStructPtr + offset),      // safe (need to adjust offset as it could be class)
                        structSize
                        );
                });
            }
        }