Last active
December 23, 2018 08:42
-
-
Save michel-pi/c5be51e87db649bfb01f2e788e6942c9 to your computer and use it in GitHub Desktop.
Import methods from .dll's at runtime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Runtime.Serialization; | |
namespace System.Runtime.InteropServices | |
{ | |
public static class DynamicImport | |
{ | |
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true, CharSet = CharSet.Ansi)] | |
private static extern IntPtr GetProcAddress(IntPtr hModule, string procname); | |
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)] | |
private static extern IntPtr LoadLibrary(string lpFileName); | |
[DllImport("kernel32.dll", EntryPoint = "GetModuleHandleW", SetLastError = true, CharSet = CharSet.Unicode)] | |
private static extern IntPtr GetModuleHandle(string modulename); | |
public static IntPtr ImportLibrary(string libraryName) | |
{ | |
if (libraryName == string.Empty) throw new ArgumentOutOfRangeException(nameof(libraryName)); | |
IntPtr hModule = GetModuleHandle(libraryName); | |
if(hModule == IntPtr.Zero) | |
{ | |
hModule = LoadLibrary(libraryName); | |
} | |
if (hModule == IntPtr.Zero) | |
{ | |
throw new DynamicImportException("DynamicImport failed to import library \"" + libraryName + "\"!"); | |
} | |
else | |
{ | |
return hModule; | |
} | |
} | |
public static IntPtr ImportMethod(IntPtr moduleHandle, string methodName) | |
{ | |
if (moduleHandle == IntPtr.Zero) throw new ArgumentOutOfRangeException(nameof(moduleHandle)); | |
if (string.IsNullOrEmpty(methodName)) throw new ArgumentOutOfRangeException(nameof(methodName)); | |
IntPtr procAddress = GetProcAddress(moduleHandle, methodName); | |
if (procAddress == IntPtr.Zero) | |
{ | |
throw new DynamicImportException("DynamicImport failed to find method \"" + methodName + "\" in module \"0x" + moduleHandle.ToString("X") + "\"!"); | |
} | |
else | |
{ | |
return procAddress; | |
} | |
} | |
public static IntPtr ImportMethod(string libraryName, string methodName) | |
{ | |
return ImportMethod(ImportLibrary(libraryName), methodName); | |
} | |
public static T Import<T>(IntPtr moduleHandle, string methodName) | |
{ | |
var address = ImportMethod(moduleHandle, methodName); | |
return Marshal.GetDelegateForFunctionPointer<T>(address); | |
} | |
public static T Import<T>(string libraryName, string methodName) | |
{ | |
var address = ImportMethod(libraryName, methodName); | |
return Marshal.GetDelegateForFunctionPointer<T>(address); | |
} | |
} | |
public class DynamicImportException : Win32Exception | |
{ | |
public DynamicImportException() | |
{ | |
} | |
public DynamicImportException(int error) : base(error) | |
{ | |
} | |
public DynamicImportException(string message) : base(message + Environment.NewLine + "ErrorCode: " + Marshal.GetLastWin32Error()) | |
{ | |
} | |
public DynamicImportException(int error, string message) : base(error, message) | |
{ | |
} | |
public DynamicImportException(string message, Exception innerException) : base(message, innerException) | |
{ | |
} | |
protected DynamicImportException(SerializationInfo info, StreamingContext context) : base(info, context) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment