/*************************************************************************************************** Copyright (C) 2023 The Qt Company Ltd. SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only ***************************************************************************************************/ using System.Collections.Concurrent; using System.Reflection; using System.Runtime.InteropServices; namespace Qt.DotNet { /// /// Provides access to managed types, allowing native code to obtain references to, and call /// constructors, static methods and instance methods. /// public partial class Adapter { /// /// Loads a .NET assembly into memory /// /// Name of the assembly or path to the assembly DLL. /// 'true' if load was successful; 'false' otherwise public static bool LoadAssembly(string assemblyName) { #if DEBUG // Compile-time signature check of delegate vs. method _ = new Delegates.LoadAssembly(LoadAssembly); #endif try { Assembly.Load(assemblyName); return true; } catch (Exception) { } if (File.Exists(Path.GetFullPath(assemblyName))) { try { Assembly.LoadFile(Path.GetFullPath(assemblyName)); return true; } catch (Exception) { } } if (File.Exists(Path.GetFullPath($"{assemblyName}.dll"))) { try { Assembly.LoadFile(Path.GetFullPath($"{assemblyName}.dll")); return true; } catch (Exception) { } } return false; } internal class DelegateRef { public GCHandle Handle { get; } public bool IsValid => Handle.IsAllocated; public Delegate Target => Handle.Target as Delegate; public IntPtr FuncPtr { get; } public DelegateRef(GCHandle handle, IntPtr funcPtr) { Handle = handle; FuncPtr = funcPtr; } } internal class ObjectRef { public GCHandle Handle { get; } public object Target => Handle.Target; public bool IsValid => Handle.IsAllocated && Handle.Target != null; public ObjectRef(GCHandle handle) { Handle = handle; } } private static ConcurrentDictionary ObjectRefs { get; } = new(); private static ConcurrentDictionary DelegateRefs { get; } = new(); private static ConcurrentDictionary <(object Target, MethodBase Method), DelegateRef> DelegatesByMethod { get; } = new(); private static ConcurrentDictionary <(ObjectRef Source, string Name, IntPtr Context), EventRelay> Events { get; } = new(); } }