コード例 #1
0
        internal static unsafe void FixupModuleCell(ModuleFixupCell *pCell)
        {
            string moduleName = GetModuleName(pCell);

            uint dllImportSearchPath    = 0;
            bool hasDllImportSearchPath = (pCell->DllImportSearchPathAndCookie & InteropDataConstants.HasDllImportSearchPath) != 0;

            if (hasDllImportSearchPath)
            {
                dllImportSearchPath = pCell->DllImportSearchPathAndCookie & ~InteropDataConstants.HasDllImportSearchPath;
            }

            Assembly callingAssembly = RuntimeAugments.Callbacks.GetAssemblyForHandle(new RuntimeTypeHandle(pCell->CallingAssemblyType));

            // First check if there's a NativeLibrary callback and call it to attempt the resolution
            IntPtr hModule = NativeLibrary.LoadLibraryCallbackStub(moduleName, callingAssembly, hasDllImportSearchPath, dllImportSearchPath);

            if (hModule == IntPtr.Zero)
            {
                // NativeLibrary callback didn't resolve the library. Use built-in rules.
                NativeLibrary.LoadLibErrorTracker loadLibErrorTracker = default;

                hModule = NativeLibrary.LoadBySearch(
                    callingAssembly,
                    searchAssemblyDirectory: false,
                    dllImportSearchPathFlags: 0,
                    ref loadLibErrorTracker,
                    moduleName);

                if (hModule == IntPtr.Zero)
                {
                    // Built-in rules didn't resolve the library. Use AssemblyLoadContext as a last chance attempt.
                    AssemblyLoadContext loadContext = AssemblyLoadContext.GetLoadContext(callingAssembly) !;
                    hModule = loadContext.GetResolvedUnmanagedDll(callingAssembly, moduleName);
                }

                if (hModule == IntPtr.Zero)
                {
                    // If the module is still unresolved, this is an error.
                    loadLibErrorTracker.Throw(moduleName);
                }
            }

            Debug.Assert(hModule != IntPtr.Zero);
            var oldValue = Interlocked.CompareExchange(ref pCell->Handle, hModule, IntPtr.Zero);

            if (oldValue != IntPtr.Zero)
            {
                // Some other thread won the race to fix it up.
                FreeLibrary(hModule);
            }
        }