123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Linq;
- using System.Collections.Concurrent;
- namespace NativeLibraryLoader
- {
- public class NativeLoader
- {
- private ConcurrentDictionary<IntPtr, Delegate> _Cache = new ConcurrentDictionary<IntPtr, Delegate>();
- private IntPtr intPtr;
- public string DLLName { get; } = string.Empty;
- public string Extension { get; } = string.Empty;
- public Boolean Loaded => intPtr != IntPtr.Zero;
- public string SearchPattern { get; set; } = string.Empty;
- public string LoadedFile =>loadedFile;
- private string loadedFile=string.Empty;
- public List<String> SearchDirectories { get; } = new List<string>();
- private IFileCheck fileCheck;
- private INativeLoader nativeLoader;
- public NativeLoader(string dllname)
- {
- fileCheck = GetPlatformFileCheck();
- nativeLoader = GetPlatformLoader();
- Extension = GetPlatformExtension();
- SearchPattern = dllname;
- if (System.IO.File.Exists(dllname))
- {
- intPtr = nativeLoader.CoreLoadLibrary(dllname);
- loadedFile = dllname;
- }
- else
- {
- DLLName = dllname;
- SearchDirectories.Add(AppContext.BaseDirectory);
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) SearchDirectories.Add(Environment.GetFolderPath(Environment.SpecialFolder.System));
- }
- Init();
- }
- public void Init()
- {
- if (Loaded) return;
- if (SearchDirectories.Count == 0) SearchDirectories.Add(AppContext.BaseDirectory);
- string path = SearchDirectories.SelectMany(x =>
- {
- try
- {
- string[] files = System.IO.Directory.GetFiles(x,"*.*", System.IO.SearchOption.AllDirectories).Where(y=>y.IndexOf(SearchPattern)>=0).ToArray();
- return files;
- }
- catch
- {
- return System.IO.Directory.GetFiles(x,"*.*", System.IO.SearchOption.TopDirectoryOnly).Where(y=>y.IndexOf(SearchPattern)>=0);
- }
- })?.FirstOrDefault(x =>
- {
- MachineType machineType = fileCheck.CheckFile(x);
- if (Environment.Is64BitProcess) return machineType == MachineType.Bit64;
- else return machineType == MachineType.Bit32;
- })??"";
- if (!string.IsNullOrEmpty(path))
- {
- intPtr = nativeLoader.CoreLoadLibrary(path);
- loadedFile = path;
- }
- }
- public T LoadFunction<T>(string enterpoint)where T :Delegate
- {
- if (intPtr == IntPtr.Zero) throw new EntryPointNotFoundException(enterpoint);
- var intptr = typeof(T).TypeHandle.Value;
- if(_Cache.TryGetValue(intptr,out var del))
- {
- return (T)del;
- }
- IntPtr proc = nativeLoader.CoreGetProcAddress(intPtr, enterpoint);
- if (proc != IntPtr.Zero)
- {
- del = Marshal.GetDelegateForFunctionPointer<T>(proc);
- _Cache[intptr] = del;
- return (T)del;
- }
- else
- {
- string s = nativeLoader.CoreGetLastError();
- }
- throw new EntryPointNotFoundException(enterpoint);
- }
- public IntPtr LoadFunction(string enterpoint)
- {
- if (intPtr == IntPtr.Zero) return intPtr;
- return nativeLoader.CoreGetProcAddress(intPtr, enterpoint);
- }
- public void Unload()
- {
- if(intPtr!=IntPtr.Zero)
- {
- nativeLoader.CoreFreeLibrary(intPtr);
- }
- intPtr = IntPtr.Zero;
- }
- private IFileCheck GetPlatformFileCheck()
- {
- if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return new Windows.PEFileCheck();
- }
- else if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- return new Linux.ELFFileCheck();
- }
- else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- return new MAC.MachOFileCheck();
- }
- throw new PlatformNotSupportedException("This platform cannot load native libraries.");
- }
- private INativeLoader GetPlatformLoader()
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return new Windows.WindowNativeLoader();
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- return new Linux.UnixNativeLoader();
- }
- else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)|| RuntimeInformation.OSDescription.ToUpper().Contains("BSD"))
- {
- return new MAC.BSDNativeLoader();
- }
- throw new PlatformNotSupportedException("This platform cannot load native libraries.");
- }
- private string GetPlatformExtension()
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return "dll";
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- return "so";
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- return "dylib";
- }
- throw new PlatformNotSupportedException("This platform cannot load native libraries.");
- }
- }
- }
|