C# 如何动态加载和卸载本机DLL文件?

C# 如何动态加载和卸载本机DLL文件?,c#,.net,pinvoke,C#,.net,Pinvoke,我有一个错误的第三方DLL文件,在执行一段时间后,开始抛出访问冲突异常。当这种情况发生时,我想重新加载该DLL文件。我该怎么做?试试这个 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr LoadLibrary(string libname); [DllImport("kernel32.dll", CharSet = CharSet.Auto

我有一个错误的第三方DLL文件,在执行一段时间后,开始抛出访问冲突异常。当这种情况发生时,我想重新加载该DLL文件。我该怎么做?

试试这个

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);

//Load
IntPtr Handle = LoadLibrary(fileName);
if (Handle == IntPtr.Zero)
{
     int errorCode = Marshal.GetLastWin32Error();
     throw new Exception(string.Format("Failed to load library (ErrorCode: {0})",errorCode));
}

//Free
if(Handle != IntPtr.Zero)
        FreeLibrary(Handle);
如果要首先调用函数,必须创建与此函数匹配的委托,然后使用WinApi
GetProcAddress

[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); 


IntPtr funcaddr = GetProcAddress(Handle,functionName);
YourFunctionDelegate function = Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate )) as YourFunctionDelegate ;
function.Invoke(pass here your parameters);

创建通过COM或其他IPC机制进行通信的工作进程。然后,当DLL死亡时,您可以重新启动工作进程。

加载DLL,调用它,然后卸载它,直到它消失

我已经改编了VB.Net示例中的以下代码


将dll加载到代理进程并终止整个进程如何?通常情况下,一个进程在违反访问权限后被视为已中断。如何做到这一点?我很少听说AppDomains。你能给出一些例子吗?因为它是一个本地dll,AppDomains对你没有帮助。您需要有第二个进程加载dll,然后使用某种形式的进程间通信在进程之间传输调用。网络远程可能是一种方式。但我自己并没有这样做。我不希望从一个已经严重损坏了内存,导致访问冲突的dll中进行干净的卸载和重新加载。dll无法跟踪其指针中哪些仍然有效。卸载时它应该如何干净地释放内存?访问冲突错误本质上是致命的。我怀疑你能用try-catch处理程序捕捉到它们,然后采取一些纠正措施。那么如何调用我的dll函数呢?当我将它们声明为
DllImport
时,这种方法不起作用,您能解决这个问题吗?您能提供一些本机代码的代码片段吗?本机代码应该如何声明,委托看起来如何?Thanks@Poma你把它弄好了吗?你能告诉我如何让GetDelegateForFunctionPointer工作吗?
  [DllImport("powrprof.dll")]
  static extern bool IsPwrHibernateAllowed();

  [DllImport("kernel32.dll")]
  static extern bool FreeLibrary(IntPtr hModule);

  [DllImport("kernel32.dll")]
  static extern bool LoadLibraryA(string hModule);

  [DllImport("kernel32.dll")]
  static extern bool GetModuleHandleExA(int dwFlags, string ModuleName, ref IntPtr phModule);

  static void Main(string[] args)
  {
        Console.WriteLine("Is Power Hibernate Allowed? " + DoIsPwrHibernateAllowed());
        Console.WriteLine("Press any key to continue...");
        Console.ReadKey();
  }

  private static bool DoIsPwrHibernateAllowed()
  {
        LoadLibraryA("powrprof.dll");
        var result = IsPwrHibernateAllowed();
        var hMod = IntPtr.Zero;
        if (GetModuleHandleExA(0, "powrprof", ref hMod))
        {
            while (FreeLibrary(hMod))
            { }
        }
        return result;
  }