delphi中採用bpl共享模塊的幾點釋疑

1. LoadPackage做了哪些事情?

LoadPackage的代碼可以從delphi的源碼(sysutils.pas)中找到

{ LoadPackage }

function LoadPackage(const Name: string): HMODULE;
begin
{$IFDEF MSWINDOWS}
  Result := SafeLoadLibrary(Name); //這裡使用windows api LoadLibraryA來以加載一個標準的dll的方式來加載(bpl本身也是一個動態鏈接庫)
{$ENDIF}
  if Result = 0 then
  begin
    raise EPackageError.CreateResFmt(@sErrorLoadingPackage,
      [Name,
       {$IFDEF MSWINDOWS}SysErrorMessage(GetLastError){$ENDIF}

  end;
  try
    InitializePackage(Result); //這裡使用winton api GetProcessAddress來取得單元的initialization部分的地址,並執行他
  except
{$IFDEF MSWINDOWS}
    FreeLibrary(Result);
{$ENDIF}
    raise;
  end;
end;

{ UnloadPackage }

procedure UnloadPackage(Module: HMODULE);
begin
  FinalizePackage(Module); //這裡執行單元的finalization部分的代碼
{$IFDEF MSWINDOWS}
  FreeLibrary(Module); //採用windows api FreeLibaray來從內存卸載動態鏈接庫
{$ENDIF}
end;

2. 在同一個應用程序(exe)中多次loadpackage,會導致加載多個bpl的實例到內存嗎?

答案是不會,bpl採用與windows動態鏈接庫一樣的方式來處理,同一個應用程序exe多次load一個相同的bpl,返回的是同一個hmodule值。進程的地址空間中只會有一份該bpl的代碼

3. 在不同的應用程序中load同一個bpl,會導致加載多個bpl的實例到進程的內存中嗎?

答案是:邏輯上每個應用程序加載到的是一份獨立的bpl實例。實際上windows採用相應的動態鏈接庫內存映射技術來處理,內存中只有一份bpl的代碼,但是邏輯上他們被很好的分隔,程序員可以當成他們是獨立的來使用。

4.假設在bpl中定義了全局變量F: integer = 100,那如果多個應用程序都加載了這個bpl並且修改F的值,那麼F的值會怎樣?

答案是,對於多個不同的應用程序a,b,c...他們所擁有的F是獨立的,互不影響的,比如

應用程序a把 F := F+1

b把F := F + 1

c把F := F + 1

此時並沒有一個公共的F = 103,而是各個應用程序中都有一個全局變量F,他們的值分別為101,101,101

发布了38 篇原创文章 · 获赞 19 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/truexf/article/details/6024527