笔记备忘: 在 C# 中进行 win32 dll 的动态加载, 调用, 和释放

来源:互联网 发布:云和数据培训 编辑:程序博客网 时间:2024/05/02 04:21
  ///
  /// win32 dll 函数动态封装调用
  ///

  ///
  /// bool flag = false;
  /// // 构造时导致 dll 被加载, 借助 using 块, 在离开时释放 dll
  /// using (CDCWrapper wrapper = new CDCWrapper())
  /// {
  ///   flag = wrapper.GetLastVerFile(163, "192.168.0.135", "", 0, "ccir", "1B2M2Y8AsgTpgAmY7PhCfg==", "d://1.dwg");
  ///   MessageBox.Show(flag.ToString());// 这个提示的时候 dll 还在内存中
  /// }
  /// MessageBox.Show(flag.ToString());// 这个提示时, dll 已经被卸载出内存了
  ///

  class CDCWrapper : IDisposable
  {
    public CDCWrapper()
    {
      loadLibray();
    }
 
    #region public function wrappers
    public bool GetLastVerFile(int nFileId, string strServerIP, string strProxyPort, int nProxyPort, string strUserNo, string strPasswd, string strSavePath)
    {
      if (libHandle == IntPtr.Zero)
        loadLibray();
 
      if (F1Invoker == null)
      {
        IntPtr f1Handle = GetProcAddress(libHandle, F1NAME);
        if (f1Handle == IntPtr.Zero)
          throw new EntryPointNotFoundException(F1NAME);
        F1Invoker = (FGetLastVerFile)Marshal.GetDelegateForFunctionPointer(f1Handle, typeof(FGetLastVerFile));
      }
      bool flag = F1Invoker(nFileId, strServerIP, strProxyPort, nProxyPort, strUserNo, strPasswd, strSavePath);
      return flag;
    }
    #endregion
 
    #region IDisposable Members
    void IDisposable.Dispose()
    {
      if (libHandle != IntPtr.Zero)
        FreeLibrary(libHandle);
    }
    #endregion
 
    #region function prototypes
    [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
    delegate bool FGetLastVerFile(int nFileId, string strServerIP, string strProxyPort, int nProxyPort, string strUserNo, string strPaswd, string strSavePath);
    #endregion
 
    #region windows kernel
    [DllImport("kernel32", CharSet = CharSet.Ansi)]
    extern static IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    extern static IntPtr LoadLibrary(string lpLibFileName);
    [DllImport("kernel32", CharSet = CharSet.Auto)]
    static extern int FreeLibrary(IntPtr hLibModule);
    #endregion
 
    void loadLibray()
    {
      if (libHandle == IntPtr.Zero)
      {
        libHandle = LoadLibrary(LIBNAME);
        if (libHandle == IntPtr.Zero)
          throw new DllNotFoundException(LIBNAME + " 加载失败, 请检查");
      }
    }
 
    #region fields
    const string LIBNAME = "CDCommu.dll";
    IntPtr libHandle = IntPtr.Zero;
    const string F1NAME = "_GetLastVerFile@28";
    FGetLastVerFile F1Invoker = null;
    #endregion
  }
原创粉丝点击