以前公司的程序是把所有的程序用EXE编译,我现在想用主程序(EXE)+业务程序(bpl)方式去做,但我把一个业务程序编译成BPL时,主程序居然SHOW不出来,自己用别的测试程序可以把我编译好的BPL能SHOW来这是什么原因呀?例如我主程序調用
   FPackageHandle := LoadPackage('aa.bpl');
   AClass := GetClass('TfrmFindPublic');
跟蹤時aclass總是NIL
而我建別的工程,去調用時
FPackageHandle := LoadPackage('aa.bpl');
   AClass := GetClass('TfrmFindPublic');
ACLASS不爲NIL也就可以SHOW出來
主程序的bulid with runtime package是打勾了
bpl包也註冊了:
initialization
  RegisterClass(TfrmFindPublic);
finalization
  UnRegisterClass(TfrmFindPublic);
end.請問這是什麽原因呀,百思不得其解,HELP!HELP!

解决方案 »

  1.   

    首先看aa.bpl的路径设置是否正确,如果不能确定,就放到system32目录中去!
    然后判断FPackageHandle是否存在,
    然后再看AClass
      

  2.   

    应该是路径问题。
    你把bpl文件放在程序目录下,
    你将路径设为绝对路径或者向系统中添加环境变量,应该就没问题了。
      

  3.   

    to SmallHand and owlet_leo路径是正确的,如果不存在系统会报错的呀,我也试过用OPENdialog去调要要的BPL也不行呀,各位高手,请你们帮帮忙
      

  4.   

    var 
    AClass: TPersistentClass;
     AForm: TForm;
    begin
    if FPackageHandle=0 then
      if dlgOpen1.Execute then
          FPackageHandle := LoadPackage(dlgOpen1.FileName);
    if FPackageHandle <> 0 thenbeginAClass := GetClass('TfrmFindPublic'); if AClass <> nil then
      begin
        //FindPublicShow(TRSPDBGrid(ActiveControl), s, i);
       // Application.CreateForm(TComponentClass(AClass), AForm);
       // AForm.Show;
          with   TComponentClass(AClass).Create(Application)
                      as   TCustomForm   do
                  begin
                      ShowModal;
                      Free;
                  end;
      end;
    ========上面的是业务程序调用,显示不出来=============
    var
      AClass: TClass;
      AForm: TForm;
    beginif FPackageHandle=0 then  showmessage(ExtractFilePath(Application.ExeName)+'PUB_find.bpl');
      FPackageHandle := LoadPackage(ExtractFilePath(Application.ExeName)+'PUB_find.bpl');
      AClass := GetClass('TfrmFindPublic');
      if AClass <> nil then
      begin
       // Application.CreateForm(TComponentClass(AClass), AForm);
        //AForm.Show;
        with   TComponentClass(AClass).Create(Application)
                      as   TCustomForm   do
                  begin
                      ShowModal;
                      Free;
                  end;        //  UnloadPackage(FPackageHandle);  }
      end;
    ===========这个是自己的测试可以SHOW出来========
      

  5.   

    FPackageHandle 业务程序中 这个为0 ?LoadPackage失败了吧看看dlgOpen1.FileName 返回的是什么
      

  6.   

    var
    AClass: TPersistentClass;
    AForm: TForm;
    begin
    if FPackageHandle=0 then
      if dlgOpen1.Execute then
          FPackageHandle := LoadPackage(dlgOpen1.FileName);showmessage(IntToStr(FPackageHandle))//看看是否调用成功
    if FPackageHandle <> 0 thenbegin

    AClass := GetClass('TfrmFindPublic');
     F5,设置断点,然后运行单步跟踪if AClass <> nil then
      begin
        //FindPublicShow(TRSPDBGrid(ActiveControl), s, i);
      // Application.CreateForm(TComponentClass(AClass), AForm);
      // AForm.Show;
          with  TComponentClass(AClass).Create(Application)
                      as  TCustomForm  do
                  begin
                      ShowModal;
                      Free;
                  end;
      end; 
      

  7.   

    LoadPackageGetClass('TfrmFindPublic');
    这两个都返回什么还是
    GetClass('TfrmFindPublic');根本就没执行
      

  8.   

    FPackageHandle是來看一下沒有加這個包的,loadpackage沒有失败的
      

  9.   

    LoadPackage有执行,但GetClass('TfrmFindPublic')执行了,但返回的是NIL
      

  10.   


    AClass := GetClass('TfrmFindPublic'); F5,设置断点,返回的是ACLASS=NIL,但我的包里是有存在TfrmFindPublic的窗体名
      

  11.   

    你这样调用:AClass := Classes.GetClass('TfrmFindPublic');
      

  12.   

    if FPackageHandle=0 then
      if dlgOpen1.Execute then
          FPackageHandle := LoadPackage(dlgOpen1.FileName); 
    这个有执行嘛,你确定 LoadPackage 的bpl是你预期的bpl嘛输出dlgOpen1.FileName 这个看看
      

  13.   

    AClass := GetClass('TfrmFindPublic'); F5,设置断点,然后运行单步跟踪 
    要跟踪,应该在这句之后设置断点,断点设在赋值语句上有可能导致未赋值。
    比如:
    AClass := GetClass('TfrmFindPublic'); F5,设置断点,然后运行单步跟踪 
    Caption:= 'For break';//<--断点设在这里观察AClass的值。
      

  14.   

    我这样可以,程序就可以看到 类啊。
    procedure TMainForm.btnExitClick(Sender: TObject);
    var
      m_frmClass: TPersistentClass;
      m_fc: TMainForm;
      m_HModule: HMODULE;
    begin
      m_HModule:= LoadPackage('Package1.bpl');//bpl在程序目录下,在程序目录下启动程序。
      if m_HModule= 0 then
        Exit;
      RegisterClass(TMainForm);
      m_frmClass:= GetClass('TMainForm');
      if m_frmClass= nil then
        ShowMessage('Error,not found class');
      ShowMessage(m_frmClass.ClassName);
    end;
      

  15.   

    要不,你把问题代码所在窗体及代码发给我,不需要bpl,我调一下看看。
      

  16.   

    RegisterClass(TMainForm)没有作用吧
      

  17.   

    没有理由啊!关键是你的测试代码是可以执行的,证明bpl没有问题!
    你再看看是不是其他什么地方,消息啊什么的干扰了!?
      

  18.   

    TMainform是bpl中的一个窗体类。
      

  19.   

    这个也许有帮助
    http://edn.embarcadero.com/article/27178
      

  20.   

    貌似选上Build with runtime packages就好了
      

  21.   

    你用其他的项目可以执行,恐怕是因为你使用了使用运行时包的缘故。
    如果要减少对运行时包的依赖,可以尝试,将Build with runtime package下面的编辑框中只保留Vcl一项,这样可以最大程度的减少程序对运行时包的依赖性,这时,就可以动态加载包了,但我觉得这样还不如使用DLL来封装,因为最少也要再包括一个vclxx.bpl(xx对应于你使用的Delphi版本)。
    还是尽可能使用DLL封装吧。
      

  22.   

    使用排除法吧,就是把所有其他的都剥离,只留主框架+bpl,然后跟踪测试!
      

  23.   

    首先要说明,我在22、26、27楼中的说法是不完全对了。可忽略这三楼,尽量减少影响。包的动态加载特性好像是依赖于vclxx.bpl(我这里是vcl70.bpl)的。
    我不选中Build with runtime package的话,是找不到动态加载的包中的类的。
    如果选中该选项编译,而去掉vclxx.bpl的话,会报运行时异常,程序终止,所以,包依赖于vclxx.bpl。
    我的情况是,选中后,仅保留vcl70.bpl,窗体没有加任何控件,如果加了很多扩展控件,恐怕,还要动态加载其他的运行包。