通过GetModuleHandle/LoadLibrary加载DLL并使用FreeLibrary

kob*_*bik 3 windows delphi api winapi

这是我的代码:

function GetProcedureAddress(var P: FARPROC; const ModuleName, ProcName: AnsiString): Boolean;
var
  ModuleHandle: HMODULE;
begin
  Result := False;
  ModuleHandle := GetModuleHandle(PAnsiChar(AnsiString(ModuleName)));
  if ModuleHandle = 0 then
    ModuleHandle := LoadLibrary(PAnsiChar(ModuleName)); // DO WE NEED TO CALL  FreeLibrary ?
  if ModuleHandle <> 0 then
  begin
    P := Pointer(GetProcAddress(ModuleHandle, PAnsiChar(ProcName)));
    if Assigned(P) then
      Result := True;
  end;
end;

function PathMakeSystemFolder(Path: AnsiString): Boolean;
var
  _PathMakeSystemFolderA: function(pszPath: PAnsiChar): BOOL; stdcall;
begin
  Result := False;
  if GetProcedureAddress(@_PathMakeSystemFolderA, 'shlwapi.dll', 'PathMakeSystemFolderA') then
    Result := _PathMakeSystemFolderA(PChar(Path));
end;
Run Code Online (Sandbox Code Playgroud)

如果使用LoadLibrary,我们需要调用FreeLibrary吗?或者当我的申请终止时,它的引用计数会自动递减?

mka*_*aes 6

我将从这里引用.

系统在所有已加载的模块上维护每个进程的引用计数.调用LoadLibrary会增加引用计数.调用FreeLibrary或FreeLibraryAndExitThread函数会减少引用计数.系统在其引用计数达到零或进程终止时(无论引用计数如何)卸载模块.

所以基本上你不需要打电话,FreeLibrary但你应该考虑这样做.我个人认为,如果资源处理不当,这是一个错误.

  • 对你的最后一句话:"我个人认为这是一个错误,当资源没有被正确处理",正确的,在LoadLibrary和FreeLibrary则的情况下,还包括允许基于处理终止自动释放.我建议删除这句话,因为它会推动读者弊大于利. (3认同)
  • @kobik - 如果将引用计数增加1或10并不重要,则dll将仅映射到进程地址空间一次.在资源方面使用LoadLibrary对GetModuleHandle没有任何惩罚.答案的意思是,当你完成它时,最好是免费使用它. (2认同)