关于使用包(bpl)碰到的极奇怪的现象

leeky 2008-03-14 01:52:37
目前正在做一項目,考慮到方便管理及升级的需要,就使用主程序与多个包的形式實現。
其中有些包包含全局變量或对象,还有的包包含要被调用的函数,所以把它們加到Build with runtime packages中。
碰到以下問題:
1、在做好包后,在主程序中调用都正常;某次輸入代碼把变量输错,Delphi就在也不能出来提示信息,如输入"ShowMessage(",消息栏里立即提示由於代碼存在錯誤,所以不能唤起提示。但把这语句录完,而運行时又是正常的。
以上现象在多次从零构建主程序后都出现(只要你某次不小心输错代碼),一直如此,如果代碼有错,出错提示却在實際出借代碼之上几行的位置;
2、我在主程序中使用动态數組記錄各个bpl的版本等信息,
TPkgInfo = record
FileName : ShortString;
Size : integer;
DateTime : TDateTime;

PkgType : integer;
ClassName : ShortString; //本包输出的类名;
Version : ShortString; //版本信息。
//……还有其它一些信息
end;

var
PkgInfos : array of TPkgInfo;

在主程序中读取所有包信息及顯示出來都正确。
如以下代碼:
PkgInfos[bplCnt-1].ClassName := GetFileBuildInfo(tmpStr,'ClassName');
with PkgInfos[bplCnt-1] do
Memo1.Lines.Add('文件名:'+FileName+';版本:'+Version+';类名:'+ClassName);
程序運行正常,但由於我发现示的类名是我主窗体的类名,并不是我想要的包中的类名,所以我修改記錄類型TPkgInfo,把ClassName改为AClassName,同时在程序中作相应修改。这时提示后面的显示代碼中的"AClassName"未定義了!!我屏蔽掉顯示,程序運行正常,
这时我突发奇想,把赋值语句
PkgInfos[bplCnt-1].ClassName := GetFileBuildInfo(tmpStr,'ClassName');
改为:
PkgInfos[bplCnt-1].NNNClassName := GetFileBuildInfo(tmpStr,'ClassName');
程序居然也能運行!!这是什麽回事?
我懷疑Delphi沒有重新編譯,于是又在这代碼之前加了个ShowMessage调用,實際運行也顯示了消息,我就不明白隨便AClassName改成啥東西,程序都能運行!

请哪位高人解释一下?如果以前碰到过就好了。
先放50分,如有好的建議,我到時再加分
...全文
136 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
leeky 2008-03-20
  • 打赏
  • 举报
回复
本来想试下"无满意结帖"(主要为尝个新鲜),但看在兄弟们费神的前提下,给分吧.
leeky 2008-03-20
  • 打赏
  • 举报
回复
自己搞定了.
禹爸爸 2008-03-14
  • 打赏
  • 举报
回复
同意楼上两位的说法。
如果修改了BPL,应该重新编译一下,特别是做为基础的BPL
tpcnyou 2008-03-14
  • 打赏
  • 举报
回复
如果修改了基础包,应该把所有的bpl都重新Build All一下
否则很容易出现未知的错误。
火星牛 2008-03-14
  • 打赏
  • 举报
回复
我一直用bpl组装系统。
你上面的“怪”现象,一般是因为修改后的dpk没有重编译出现的。修改了dpk中的代码,自己重编译以下就行了。
我一般把dpk的options-descriptions-build control设为Rebuild as needed,即让IDE判断,认为需要重编译就自己自动重编译。
leeky 2008-03-14
  • 打赏
  • 举报
回复
没辙了,常规的方法我试了两天了啊.
包括: 1\多次从新建立测试窗体;
2\删除有关的dcu、dcp、bpl文件。
++++++++++++++++++++++++++++++++++++++++++++++++++
如以下的代码:
PkgInfos[bplCnt-1].Version := GetFileBuildInfotmpStr,'FileVersion'); //版本信息。
PkgInfos[bplCnt-1].ClassName := GetFileBuildInfo(tmpStr,'ClassName'); //本包输出的类名;
PkgInfos[bplCnt-1].Author := GetFileBuildInfo(tmpStr,'Author');
//上面的赋值没问题,跟踪可以查看到全部属性
//下一语句不能引用Author等。
Memo1.Lines.Add('被检测的包:'+PkgInfos[bplCnt-1].FileName+';作者:'+PkgInfos[bplCnt-1].Author);

以上为PkgInfos[bplCnt-1]的属性赋值不出错,但Memo1.Lines.Add中如果使用Author,ClassName等就出错.如屏蔽掉以上的Memo1.Lines.Add(...)语句就能运行,否则通不过,说是Author未定义.
Harryfin 2008-03-14
  • 打赏
  • 举报
回复
其实程序倒没有错,但就是没有了贴身的提示,比较不方便.输入个方法,不给出参数原型,输入对象名,得不到相关属性.
-------------------------------
有时重新编译下就有了,哪怕编译出错
leeky 2008-03-14
  • 打赏
  • 举报
回复
我现在已经回归到最简模式,基础包就是一个AppAddin.dpk,只包含一个单元,代码如下:
(包信息结构及对包信息管理的动态数组是在主窗体中定义的,一定义就没有相关提示了,但又能正常运行)
为避免其它问题,我现在把所有的代码都放到同一个目录下了。
unit PkgUtils;

interface

uses
Windows, SysUtils, Classes, Forms, Controls;

{ Package }
function GetAddinPackages: TStrings;
function LoadAddinPackage(const PackageID, FileName: string): HMODULE;
procedure UnloadAddinPackage(ModuleInstance: HMODULE); overload;
procedure UnloadAddinPackage(const PackageID: string); overload;
procedure UnloadAddins;

{ Form }
function CreateFormByClassName(const ClassName: string): TCustomForm;
function ShowModalFormByClassName(const ClassName: string): integer;

//leeee
function CreateFrameByClassName(const ClassName: string): TCustomFrame;
//function ShowModalFrameByClassName(const ClassName: string): integer;

implementation

var
AddinPackages: TStrings;

resourcestring
sErrorCreateForm = '创建表单错误';

function GetAddinPackages: TStrings;
begin
Result := AddinPackages;
end;

function LoadAddinPackage(const PackageID, FileName: string): HMODULE;
var
ModuleInstance: HMODULE;
begin
ModuleInstance := GetModuleHandle(PChar(ExtractFileName(FileName)));
if ModuleInstance = 0 then
begin
ModuleInstance := LoadPackage(FileName);
if AddinPackages.IndexOfObject(Pointer(ModuleInstance)) < 0 then
AddinPackages.AddObject(UpperCase(PackageID), Pointer(ModuleInstance));
end;
Result := ModuleInstance;
end;

procedure UnloadAddInPackage(ModuleInstance: HMODULE);
var
i: Integer;
M: TMemoryBasicInformation;
begin
for i := Application.ComponentCount - 1 downto 0 do
begin
VirtualQuery(GetClass(Application.Components[i].ClassName), M, SizeOf(M));
if (ModuleInstance = 0) or (HMODULE(M.AllocationBase) = ModuleInstance) then
Application.Components[i].Free;
end;
UnRegisterModuleClasses(ModuleInstance);
UnloadPackage(ModuleInstance);
end;

procedure UnloadAddinPackage(const PackageID: string);
var
i: integer;
begin
i := AddinPackages.IndexOf(UpperCase(PackageID));
if i < 0 then
Exit;

UnloadAddinPackage(HMODULE(AddinPackages.Objects[i]));

AddinPackages.Delete(i);
end;

procedure UnloadAddins;
var
i: integer;
begin
for i := 0 to AddinPackages.Count-1 do
UnloadAddinPackage(HMODULE(AddinPackages.Objects[i]));
AddinPackages.Clear;
end;

function CreateFormByClassName(const ClassName: string): TCustomForm;
var
AClass: TPersistentClass;
begin
AClass := GetClass(ClassName);
if AClass <> nil then
Result := TComponentClass(AClass).Create(Application) as TCustomForm
else
raise Exception.CreateFmt(sErrorCreateForm, [ClassName]);
end;

function ShowModalFormByClassName(const ClassName: string): integer;
var
frm: TCustomForm;
begin
frm := CreateFormByClassName(ClassName);
try
Result := frm.ShowModal;
finally
frm.Release;
end;
end;
//-----------------------------------------------------------------------------
function CreateFrameByClassName(const ClassName: string): TCustomFrame;
var
AClass: TPersistentClass;
begin
AClass := GetClass(ClassName);
if AClass <> nil then
Result := TComponentClass(AClass).Create(Application) as TCustomFrame
else
raise Exception.CreateFmt(sErrorCreateForm, [ClassName]);
end;

//----------------------------------------
initialization
AddinPackages := TStringList.Create;
finalization
AddinPackages.Free;

end.
leeky 2008-03-14
  • 打赏
  • 举报
回复
如果主窗体没有被编译,那么我加入测试的ShowMessage('....')就不会起作用,而实际效果是它已经发生作用.
我给delphi7打了补丁还是一样.
其实程序倒没有错,但就是没有了贴身的提示,比较不方便.输入个方法,不给出参数原型,输入对象名,得不到相关属性.
头大了……
leeky 2008-03-14
  • 打赏
  • 举报
回复
同志,你们要看到:我修改的代码是在主程序中的.
今天又发现:以上的问题是出现在结构体TPkgInfo定义之后,如果我屏蔽掉此定义代码,输入ShowMessage(时依然不能给出提示信息,显示为代码错误引发的,如果把TPkgInfo删除,则能提示.

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧