有一用Delphi做成的现成系统,我手头只有可执行程序,没有源代码,也没有文档,该系统有很多的BPL文件,我现在需要调用一下该系统的功能,我如何去着手?怎样分析这些BPL文件,还有如何调用里面的函数,类啊什么的??大家帮忙提供一下思路。。

解决方案 »

  1.   


    主要是这部分Dynamically loaded BPLsBPLs are just as simple. Well almost.We dynamically load the package by using the LoadPackage function.function LoadPackage(const Name: string): HMODULE;We create TPersistentClass of the class we wish to instantiate by using the GetClass function.function GetClass(const AClassName: string):
      TPersistentClass;Instantiate an object of the loaded class and use it.And when we are done, unload the package using the UnloadPackage procedure.procedure UnloadPackage(Module: HMODULE);Let us go back to our example and make a few changes:   1. Select "Project1.exe" from the project manager.
       2. Right-click and select "Options..."
       3. Select the "Packages" tab.
       4. Remove "Package1" from the "Runtime packages" edit-box section and OK the options.
       5. On Delphi's toolbar, click on the "Remove file from project" button.
       6. Select "Unit2 | Form2" from the list and then "OK."
       7. Now go to the "Unit1.pas" source and remove Unit2 from its uses clause. (These steps are required to remove any link to Unit2 and the package we wish to load dynamically.)
       8. Go to the source of Button1's OnClick event.
       9. Add two variables of type HModule and TPersistentClass.      var
            PackageModule: HModule;
            AClass: TPersistentClass;  10. Load the package Package1 by using the LoadPackage function.        PackageModule := LoadPackage('Package1.bpl');  11. Check that the Package Module is not 0 (zero).
      12. Create a persistent class using the GetClass function, passing it the name of the form within the package as its parameter:        AClass := GetClass('TForm2');  13. If the persistent class is not nil, create and use an instance of the class just a before.        with TComponentClass(AClass).Create(Application)
              as TCustomForm do
            begin
              ShowModal;
              Free;
            end;  14. Finally, unload the package using the UnloadPackage procedure:        UnloadPackage(PackageModule);  15. Save the project.Here is the complete listing of the OnClick event:procedure TForm1.Button1Click(Sender: TObject);
    var
      PackageModule: HModule;
      AClass: TPersistentClass;
    begin
      PackageModule := LoadPackage('Package1.bpl');
      if PackageModule <> 0 then
      begin
        AClass := GetClass('TForm2');    if AClass <> nil then
          with TComponentClass(AClass).Create(Application)
            as TCustomForm do
          begin
            ShowModal;
            Free;
          end;    UnloadPackage(PackageModule);
      end;
    end;Unfortunately that's not the end of it.The problem is that the GetClass function requires the class to be registered before the function can find it. Usually form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. But the form isn't loaded yet. So where should we register the class? The answer: in the package. Each unit in the package is initialized when the package is loaded and finalized when the package is unloaded.Let's return to our example and make a few changes:   1. Double-click on "Package1.bpl" in the project manager; this will activate the package editor.
       2. Click on the + symbol next to "Unit2" in the "Contains" section. This will expand the unit tree.
       3. Double-click on "Unit2.pas" to activate the unit's source code.
       4. Scroll down to the end of the file and add an initialization section.
       5. Register the form's class using the RegisterClass procedure:        RegisterClass(TForm2);   6. Add a finalization section.
       7. Un-register the form's class using the UnRegisterClass procedure:        UnRegisterClass(TForm2);   8. Finally, save and compile the package.Now we can safely run the "Project1" application - it will function just as before, but with the added benefit of being able to load the package when you want to.
    FinallyMake sure you compile any project that uses packages (static or dynamic) with runtime packages turned on: "Project | Options | Packages | Build with runtime packages."You must be careful that when you unload a package you destroy any objects using those classes and un-register any classes that were registered.This procedure may help:procedure DoUnloadPackage(Module: HModule);
    var
      i: Integer;
      M: TMemoryBasicInformation;
    begin
      { Make sure there aren't any instances of any
        of the classes from Module instantiated, if
        so then free them.  (This assumes that the
        classes are owned by the application) }  for i := Application.ComponentCount - 1 downto 0 do
      begin
        VirtualQuery(
          GetClass(Application.Components[i].ClassName),
          M, SizeOf(M));
        if (Module = 0) or
          (HMODULE(M.AllocationBase) = Module) then
          Application.Components[i].Free;
      end;
      UnRegisterModuleClasses(Module);
      UnLoadPackage(Module);
    end;An application requires "knowledge" of the registered class names prior to loading the package. One way to improve this would be to create a registration mechanism to inform the application of all the class names registered by the package.