程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> bpl和dll文件的區別[翻譯]

bpl和dll文件的區別[翻譯]

編輯:Delphi
 [原文]
  
  That is correct. A BPL is a DLL. (But not all DLLs are BPLs.)
  
  > But I still found some different, such as that I can create a
  > object from the Host exe and that pass to a BPL and modify it safely, but
  > if I do same to a dll, I can not modify any referenced property of the object.

  
  When you use packages, there is only ever one copy of any unit in
  memory. One copy of Forms, one copy of SysUtils, one copy of System
  (well, most of it), one copy of StdCtrls, etc.
  
  All class-related operations, such as the "is" and "as" Operators, rely
  on class references. Class references are actually just addresses. They
  point to definitions for the layouts of the classes' internals. (They
  point to what's called the virtual-method table, the VMT.) Two classes
  are the same if they point to the same VMT -- if the addresses are equal.
  
  When you have a class defined in the EXE's copy of StdCtrls and the same
  class defined in a DLL's copy of StdCtrls, those classes will really
  have different addresses. The "is" and "as" Operators won't work with
  cross-module clases. But when you use packages, there is only one copy
  of the class, kept in vcl70.bpl, so all modules that reference that
  package will share a single class definition.
  
  Another factor is the memory manager in System. All string allocations
  ultimately call GetMem and FreeMem. If the EXE allocates a string, it
  uses its own GetMem. It then passes the string to a DLL, and the DLL
  might try to free it. The DLL will call its own copy of FreeMem, which
  won't have Access to the EXE's memory-manager structures, and you'll get
  errors. With packages, everything will use the same memory manager from
  rtl70.bpl. (This can also be solved by using a shared memory manager
  between the EXE and the DLL; ShareMem is one example. That won't solve
  the class-comparison problem, though.)
  
  Above, I said the major difference between BPLs and DLLs is the number
  of exported functions. With a DLL, the only things exported are what
  appear in the "exports" clause that you write yourself. With a BPL,
  everything from all the units' "interface" sections gets exported,
  including global variables and class definitions. Also exported are the
  addresses of the "initialization" and "finalization" sections. And,
  internally, that is indeed the major difference. A BPL exports the
  functions necessary for the RTL to recognize the file as being a BPL and
  not just a generic DLL. If you call LoadPackage, i will call LoadLibrary
  to load it like a normal DLL, and then it will call all the package's
  units' initialization sections and do a fe other housekeeping
  Operations. Calling a package's functions generates the same kind of
  assembler code as is generated when you call a DLL function.
  
  [譯文]
  
        是的, bpl是dll,  但不是所有dll都是bpl。
  
  > 但是我還是發現了一些不同,比如,
  >我可以在主應用程序中創建一個對象,把它傳遞給bpl,然後
  >我可以安全得修改它。但是如果我用dll的話,我就不能修改和
  >引用這個對象的屬性。

  

        使用packages時 ,每個單元, 每個窗體, 每個sysutils, 每個system等等在內存中都只有一份拷貝,

  所有作用於類的操作符 ,比如is和as ,都依賴於類的引用, 類的引用其實就是一個(受限的)指針,指向類的定義(就是虛函數表 vmt) 如果兩個引用指向相同的vmt,那麼它們就是同一個類的引用。
  

        如果你在exe和dll裡使用同一個在stdctrls中定義的類,這兩個類的vmt有不同的地址,is 和 as運算符在不同模塊中不能正確地工作。 但是如果你使用包,那麼內存中就只有一個類的拷貝,保存在vcl70.bpl中,那麼所有引用那個包的模塊會共享同一個類的定義。
        另一個因素就是system單元中內存管理器。所有的串分配最後都是調用getmem和freemem。如果exe分配了一個串,它使用它自己的getmem函數的拷貝,如果它把串傳給dll,在dll中去free。那麼這個dll會調用它自己的freemem函數的拷貝,而這個freemem函數不能訪問exe中的內存管理器,這樣就會產生錯誤。而如果用packages,它們都會使用rtl70.bpl中的內存管理器。(這個問題也可以通過在exe和dll間共享一個內存管理器來解決,共享內存只是個例子。但還是不能解決類之間的問題。)
  

         綜上述,我認為bpls和dlls之間的主要區別就是輸出函數的數量。用dll輸出的唯一的東西就是用exports關鍵字指定的那些。而用bpl,所有單元的interfaces裡定義的都輸出,包括全局變量和類定義,initialization和finalization部分的地址也輸出。另外,在dll和bpl的內部,確實有很大的不同。bpl輸出所有供RTI識別一個文件是bpl而不是dll文件所需的所有函數。如果你調用loadpackage,我也可以調用loadlibrary把它當作普通的dll來load,然後它會調用packages中所有單元的initializatin部分並做一些其他的housekeeping?的操作。調用包裡的函數時產生的匯編代碼和調用dll中函數產生的匯編代碼是相同的。
  
  第一次翻譯文章,很多地方翻譯得不好。 
  我覺得這篇文章很不錯,希望有時間的高手能夠重新翻譯一次,謝謝。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved