Example #1
0
        private static Delegate CreateDelegate(string assemblyPath, string typeName, string methodName, string delegateTypeName)
        {
            // Throws
            IsolatedComponentLoadContext alc = GetIsolatedComponentLoadContext(assemblyPath);

            Func <AssemblyName, Assembly> resolver = name => alc.LoadFromAssemblyName(name);

            // Throws
            Type type = Type.GetType(typeName, resolver, null, throwOnError: true) !;

            // Throws
            Type delegateType = Type.GetType(delegateTypeName, resolver, null, throwOnError: true) !;

            // Throws
            return(Delegate.CreateDelegate(delegateType, type, methodName) !);
        }
Example #2
0
        public static unsafe int LoadAssemblyAndGetFunctionPointer(IntPtr assemblyPathNative,
                                                                   IntPtr typeNameNative,
                                                                   IntPtr methodNameNative,
                                                                   IntPtr delegateTypeNative,
                                                                   IntPtr reserved,
                                                                   IntPtr functionHandle)
        {
            try
            {
                // Load the assembly and create a resolver callback for types.
                string assemblyPath = MarshalToString(assemblyPathNative, nameof(assemblyPathNative));
                IsolatedComponentLoadContext  alc      = GetIsolatedComponentLoadContext(assemblyPath);
                Func <AssemblyName, Assembly> resolver = name => alc.LoadFromAssemblyName(name);

                // Get the requested type.
                string typeName = MarshalToString(typeNameNative, nameof(typeNameNative));
                Type   type     = Type.GetType(typeName, resolver, null, throwOnError: true) !;

                // Get the method name on the type.
                string methodName = MarshalToString(methodNameNative, nameof(methodNameNative));

                // Determine the signature of the type. There are 3 possibilities:
                //  * No delegate type was supplied - use the default (i.e. ComponentEntryPoint).
                //  * A sentinel value was supplied - the function is marked UnmanagedCallersOnly. This means
                //      a function pointer can be returned without creating a delegate.
                //  * A delegate type was supplied - Load the type and create a delegate for that method.
                Type?delegateType;
                if (delegateTypeNative == IntPtr.Zero)
                {
                    delegateType = typeof(ComponentEntryPoint);
                }
                else if (delegateTypeNative == (IntPtr)(-1))
                {
                    delegateType = null;
                }
                else
                {
                    string delegateTypeName = MarshalToString(delegateTypeNative, nameof(delegateTypeNative));
                    delegateType = Type.GetType(delegateTypeName, resolver, null, throwOnError: true) !;
                }

                if (reserved != IntPtr.Zero)
                {
                    throw new ArgumentOutOfRangeException(nameof(reserved));
                }

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

                IntPtr functionPtr;
                if (delegateType == null)
                {
                    // Match search semantics of the CreateDelegate() function below.
                    BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
                    MethodInfo?  methodInfo   = type.GetMethod(methodName, bindingFlags);
                    if (methodInfo == null)
                    {
                        throw new MissingMethodException(typeName, methodName);
                    }

                    // Verify the function is properly marked.
                    if (null == methodInfo.GetCustomAttribute <UnmanagedCallersOnlyAttribute>())
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_FunctionMissingUnmanagedCallersOnly);
                    }

                    functionPtr = methodInfo.MethodHandle.GetFunctionPointer();
                }
                else
                {
                    Delegate d = Delegate.CreateDelegate(delegateType, type, methodName) !;

                    functionPtr = Marshal.GetFunctionPointerForDelegate(d);

                    lock (s_delegates)
                    {
                        // Keep a reference to the delegate to prevent it from being garbage collected
                        s_delegates[functionPtr] = d;
                    }
                }

                *(IntPtr *)functionHandle = functionPtr;
            }
            catch (Exception e)
            {
                return(e.HResult);
            }

            return(0);
        }