程序中要动态调用自编的bpl包,如何获得其中注册的单元?

解决方案 »

  1.   

    注册的类吧RegisterClass / FindClass
      

  2.   

    我用了个笨方法。在bpl包里Exports一个方法
    function GetPackageClass(AClassName: String): TPersistentClass;然后再由主exe去调用。不过去年看过一个帖子,好像加几句汇编代码就可以了,不过现在忘了。
      

  3.   

    先谢谢两位,问题是有很多bpl包,我不能确定要打开的包里都注册了哪些类,也就是不知道AClassName,我现在想做的就是取出里面RegisterClass 注册的那些类的名称。
      

  4.   

    GetPackageInfo Routine
     
    Enumerates all the units and required packages for a package.
     [Delphi] procedure GetPackageInfo(Module: Cardinal, Param: Pointer, var Flags: Integer, InfoProc: TPackageInfoProc);
    Description 
    Call GetPackageInfo to process the information in a package's information table. The InfoProc callback is called for every unit included in the package and for every package required by the package. Module is the module handle for the package. GetPackageInfo passes any application-supplied information passed in the Param parameter to the InfoProc callback. The package's information flags are passed to the InfoProc and returned in the Flags parameter.
      

  5.   

    procedure ShowInfoProc (const Name: string;
      NameType: TNameType; Flags: Byte; Param: Pointer);
    var
      FlagStr: string;
    begin
      FlagStr := ' ';
      if Flags and ufMainUnit <> 0 then
        FlagStr := FlagStr + 'Main Unit ';
      if Flags and ufPackageUnit <> 0 then
        FlagStr := FlagStr + 'Package Unit ';
      if Flags and ufWeakUnit <> 0 then
        FlagStr := FlagStr + 'Weak Unit ';
      if FlagStr <> ' ' then
        FlagStr := ' (' + FlagStr + ')';
      with Form1.TreeView1.Items do
        case NameType of
          ntContainsUnit:
            AddChild (ContNode, Name + FlagStr);
          ntRequiresPackage:
            AddChild (ReqNode, Name);
        end;
    end;function ForEachModule (HInstance: Longint;
      Data: Pointer): Boolean;
    var
      Flags: Integer;
      ModuleName, ModuleDesc: string;
      ModuleNode: TTreeNode;
    begin
      with Form1.TreeView1.Items do
      begin
        SetLength (ModuleName, 200);
        GetModuleFileName (HInstance,
          PChar (ModuleName), Length (ModuleName));
        ModuleName := PChar (ModuleName); // fixup
        ModuleNode := Add (nil, ModuleName);    // get description and add fixed nodes
        ModuleDesc := GetPackageDescription (PChar (ModuleName));
        ContNode := AddChild (ModuleNode, 'Contains');
        ReqNode := AddChild (ModuleNode, 'Requires');    // add information if the module is a package
        GetPackageInfo (HInstance, nil,
          Flags, ShowInfoProc);
        if ModuleDesc <> '' then
        begin
          AddChild (ModuleNode,
            'Description: ' + ModuleDesc);
          if Flags and pfDesignOnly = pfDesignOnly then
            AddChild (ModuleNode, 'Design Only');
          if Flags and pfRunOnly = pfRunOnly then
            AddChild (ModuleNode, 'Run Only');
        end;
      end;
      Result := True;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      EnumModules(ForEachModule, nil);
    end;http://www.marcocantu.com/code/md6htm/PackInfo.htm
      

  6.   

    GetPackageInfo取到的是unit name而不是class name,要使用包里注册的类必须知道classname嘛
      

  7.   

    http://www.zahui.com/html/2/5779.htm不知道修改能不能得到,估计可以,关键就是:  oldProc := @Classes.RegisterComponentsProc;
      Classes.RegisterComponentsProc := @RegComponentsProc;
      

  8.   

    aiirii兄提到的那个例子以前就试过,但他是用GetProcAddress(unitname@register$qqrv),始终没有返回值,不知道什么原因,我试过用classname 代替unitname也不行
      

  9.   

    跟这个没有关系的,看我上面的说法,关键是将 替换掉 RegisterClass 成自己的函数
    应该是可行的。
      

  10.   

    我看了bpl包输出结构,里面没有register$qqrv的函数,我是在initliazation 部分声明了registerclass,和那个程序里的不一样,那个程序适合组件包,而我是为了分割程序模块做的程序包,问题我不知道哪个函数是registerclass的