コード例 #1
0
ファイル: KhronosApi.cs プロジェクト: nmcveity/OpenGL.Net
        /// <summary>
        /// Link delegates fields using import declarations.
        /// </summary>
        /// <param name="path">
        /// A <see cref="String"/> that specifies the assembly file path containing the import functions.
        /// </param>
        /// <param name="functionContext">
        /// A <see cref="FunctionContext"/> mapping a <see cref="MethodInfo"/> with the relative function name.
        /// </param>
        /// <param name="function">
        /// A <see cref="FieldInfo"/> that specifies the underlying function field to be updated.
        /// </param>
        /// <param name="getAddress">
        /// A <see cref="GetAddressDelegate"/> used for getting function pointers. This parameter is dependent on the currently running platform.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="path"/>, <paramref name="function"/> or <paramref name="getAddress"/> is null.
        /// </exception>
        private static void BindAPIFunction(string path, FunctionContext functionContext, FieldInfo function, GetAddressDelegate getAddress)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (functionContext == null)
            {
                throw new ArgumentNullException("functionContext");
            }
            if (function == null)
            {
                throw new ArgumentNullException("function");
            }
            if (getAddress == null)
            {
                throw new ArgumentNullException("getAddress");
            }

            Attribute[] aliasOfAttributes = Attribute.GetCustomAttributes(function, typeof(AliasOfAttribute));
            string      importName        = function.Name.Substring(1);           // Delegate name always prefixes with 'p'
            IntPtr      importAddress     = IntPtr.Zero;

            // Manages aliases (load external symbol)
            if (aliasOfAttributes.Length > 0)
            {
                for (int i = 0; i < aliasOfAttributes.Length; i++)
                {
                    AliasOfAttribute aliasOfAttribute = (AliasOfAttribute)aliasOfAttributes[i];
                    if ((importAddress = getAddress(path, aliasOfAttribute.SymbolName)) != IntPtr.Zero)
                    {
                        break;
                    }
                }
            }
            else
            {
                importAddress = getAddress(path, importName);
            }

            if (importAddress != IntPtr.Zero)
            {
                Delegate delegatePtr;

                // Try to load external symbol
                if ((delegatePtr = Marshal.GetDelegateForFunctionPointer(importAddress, function.FieldType)) == null)
                {
                    MethodInfo methodInfo;

                    if (functionContext.Imports.TryGetValue(importName, out methodInfo) == true)
                    {
                        delegatePtr = Delegate.CreateDelegate(function.FieldType, methodInfo);
                    }
                }

                if (delegatePtr != null)
                {
                    function.SetValue(null, delegatePtr);
                }
            }
            else
            {
                function.SetValue(null, null);                                          // Function not implemented
            }
        }
コード例 #2
0
        /// <summary>
        /// Link delegates fields using import declarations.
        /// </summary>
        /// <param name="path">
        /// A <see cref="String"/> that specifies the assembly file path containing the import functions.
        /// </param>
        /// <param name="getAddress">
        /// A <see cref="GetAddressDelegate"/> used for getting function pointers. This parameter is dependent on the currently running platform.
        /// </param>
        /// <param name="functionContext">
        /// A <see cref="FunctionContext"/> mapping a <see cref="MethodInfo"/> with the relative function name.
        /// </param>
        /// <param name="function">
        /// A <see cref="FieldInfo"/> that specifies the underlying function field to be updated.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="path"/>, <paramref name="function"/> or <paramref name="getAddress"/> is null.
        /// </exception>
        private static void BindAPIFunction(string path, GetAddressDelegate getAddress, FunctionContext functionContext, FieldInfo function, KhronosVersion version, ExtensionsCollection extensions)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (functionContext == null)
            {
                throw new ArgumentNullException("functionContext");
            }
            if (function == null)
            {
                throw new ArgumentNullException("function");
            }
            if (getAddress == null)
            {
                throw new ArgumentNullException("getAddress");
            }

            if (version != null || extensions != null)
            {
                if (IsCompatibleField(function, version, extensions) == false)
                {
                    function.SetValue(null, null);                                              // Function not supported: reset
                    return;
                }
            }

            string importName    = function.Name.Substring(1);                    // Delegate name always prefixes with 'p'
            IntPtr importAddress = IntPtr.Zero;

            // Load command address
            importAddress = getAddress(path, importName);

            // Manages aliases (load external symbol)
            if (importAddress == IntPtr.Zero)
            {
#if !NETCORE
                Attribute[] aliasOfAttributes = Attribute.GetCustomAttributes(function, typeof(AliasOfAttribute));
#else
                Attribute[] aliasOfAttributes = new List <Attribute>(function.GetCustomAttributes(typeof(AliasOfAttribute))).ToArray();
#endif

                for (int i = 1 /* Skip base name */; i < aliasOfAttributes.Length; i++)
                {
                    AliasOfAttribute aliasOfAttribute = (AliasOfAttribute)aliasOfAttributes[i];
                    if ((importAddress = getAddress(path, aliasOfAttribute.SymbolName)) != IntPtr.Zero)
                    {
                        break;
                    }
                }
            }

            if (importAddress != IntPtr.Zero)
            {
                Delegate delegatePtr;

                // Try to load external symbol
                if ((delegatePtr = Marshal.GetDelegateForFunctionPointer(importAddress, function.FieldType)) == null)
                {
                    MethodInfo methodInfo;

                    if (functionContext.Imports.TryGetValue(importName, out methodInfo) == true)
                    {
#if !NETCORE
                        delegatePtr = Delegate.CreateDelegate(function.FieldType, methodInfo);
#else
                        delegatePtr = methodInfo.CreateDelegate(function.FieldType);
#endif
                    }
                }

                if (delegatePtr != null)
                {
                    function.SetValue(null, delegatePtr);
                }
            }
            else
            {
                function.SetValue(null, null);                                          // Function not implemented: reset
            }
        }