public NativeDll(string path) { _dllHandle = Kernel32Dll.LoadLibrary(path); if (_dllHandle == IntPtr.Zero) { throw new InteropException("LoadLibrary failed to load native.dll"); } IntPtr procAddress = IntPtr.Zero; if ((procAddress = Kernel32Dll.GetProcAddress(_dllHandle, "SetupSubclass")) == IntPtr.Zero) { throw new InteropException("SetupSubclass function is not present in native.dll"); } _setupSubclassFunc = (BoolActionOnIntPtr)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(BoolActionOnIntPtr)); if ((procAddress = Kernel32Dll.GetProcAddress(_dllHandle, "TearDownSubclass")) == IntPtr.Zero) { throw new InteropException("TearDownSubclass function is not present in native.dll"); } _tearDownFunc = (BoolAction)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(BoolAction)); if ((procAddress = Kernel32Dll.GetProcAddress(_dllHandle, "IsSubclassed")) == IntPtr.Zero) { throw new InteropException("TearDownSubclass function is not present in native.dll"); } _isSubclassedFunc = (BoolAction)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(BoolAction)); }