using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices; namespace NZSDK_CSharpSample { public class DynamicLibraryLoader : IDisposable { #region Fields protected IntPtr ptrLibHandle; protected string debugFileName; protected string releaseFileName; protected string directoryPath; protected Dictionary dicProcAddresses = new Dictionary(); #endregion #region Constructors public DynamicLibraryLoader() { if (Assembly.GetExecutingAssembly() != null) directoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } #endregion #region Properties /// /// Gets or sets directory for library. /// public string DirectoryPath { get { return directoryPath; } set { directoryPath = value; } } /// /// Gets file name for debug /// public string DebugFileName { get { return debugFileName; } set { debugFileName = value; } } protected string DebugFilePath { get { if (String.IsNullOrEmpty(directoryPath)) return debugFileName; return Path.Combine(directoryPath, debugFileName); } } /// /// Gets file name for release /// public string ReleaseFileName { get { return releaseFileName; } set { releaseFileName = value; } } protected string ReleaseFilePath { get { if (String.IsNullOrEmpty(directoryPath)) return releaseFileName; return Path.Combine(directoryPath, releaseFileName); } } /// /// Gets handle /// public IntPtr LibraryHandle { get { return ptrLibHandle; } } /// /// Is loaded? /// public bool IsLoaded { get { return (ptrLibHandle != IntPtr.Zero); } } #endregion #region Private / Protected Methods #endregion #region Public Methods public virtual bool Load() { if (IsLoaded) { return true; } try { if (!String.IsNullOrEmpty(debugFileName) && File.Exists(DebugFilePath)) { ptrLibHandle = WinAPI.LoadLibraryEx(DebugFilePath, IntPtr.Zero, 0); if (ptrLibHandle != IntPtr.Zero) return true; } if (String.IsNullOrEmpty(releaseFileName) || !File.Exists(ReleaseFilePath)) return false; if (Directory.Exists(directoryPath)) { WinAPI.SetDllDirectory(DirectoryPath); } ptrLibHandle = WinAPI.LoadLibraryEx(ReleaseFilePath, IntPtr.Zero, 0); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); return false; } if (ptrLibHandle == IntPtr.Zero) { Debug.WriteLine(String.Format("Error Code : {0}", Marshal.GetLastWin32Error())); return false; } return true; } public virtual void Free() { if (IsLoaded == false) { return; } try { WinAPI.FreeLibrary(ptrLibHandle); ptrLibHandle = IntPtr.Zero; dicProcAddresses.Clear(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } public IntPtr GetProcAddress(Enum eFunction) { return GetProcAddress(eFunction.ToString()); } public IntPtr GetProcAddress(string functionName) { if (!IsLoaded) { throw new Exception("The library was not loaded."); } if (dicProcAddresses.ContainsKey(functionName)) return dicProcAddresses[functionName]; IntPtr ptrFunction = WinAPI.GetProcAddress(ptrLibHandle, functionName); if (ptrFunction == IntPtr.Zero) Debug.WriteLine(String.Format("Can't get '{0}' function address. The error code is {1}", functionName, Marshal.GetLastWin32Error())); dicProcAddresses[functionName] = ptrFunction; return ptrFunction; } public Delegate GetProcAddress(string functionName, Type t) { IntPtr ptr = GetProcAddress(functionName); if (ptr == IntPtr.Zero) return null; return Marshal.GetDelegateForFunctionPointer(ptr, t); } public virtual void Dispose() { Free(); } #endregion } }