在列表中添加类对象,但是进行引用或使用时则出错,大家来帮我分析一下!(50分)

  • 主题发起人 主题发起人 forlov
  • 开始时间 开始时间
F

forlov

Unregistered / Unconfirmed
GUEST, unregistred user!
Type
TPlugIn=Class(TObject)
Private
Name: String;
Caption: String;
Handle: HModule;
PType: String;
FileName: String;
Protected
InitPlugIn: TInitOperDLL;
OpenDLLForm: TOpenDLLForm;
GetDLLForm: TGetDLLForm;
PlugInLink: TGetPlugInBuilder;
Public
Constructor Create
OverLoad
Virtual;
Destructor Destroy
Override;
End;

Type
TPlugInManager=Class(TObject)
Private
FName: String;
PlugInLibraryDir: String;
FModuleList: TList;
Protected
Public
Property Name: String Read FName Write FName;
Property PlugInCount: Integer Read FObjCount;
Function LoadingDLL(FileName: String): Boolean;
Procedure OpenDLLForm(FormName, FormCaption, PlugInFilePath: String);
Published
Constructor Create
OverLoad
Virtual;
Destructor Destroy
Override;
End;

Constructor TPlugIn.Create;
Begin
Inherited Create;
End;

Destructor TPlugIn.Destroy;
Begin
Inherited Destroy;
End;

Function TPlugInManager.LoadingDLL(FileName: String): Boolean;//加载DLL文件
Var
Module: HMODULE;
p: PModuleInfo;
x: TPlugIn;
Begin
Result:=False;
if FileExists(FileName) Then
Begin
Module:=0;
Try
Module:=LoadLibrary(PChar(FileName));
Except
on E: Exception do
Begin
MessageBox(Application.Handle, pchar(E.Message), Pchar(Application.Title), MB_OK + MB_ICONERROR);
Module:=0;
End;
End;
If Module>0 then
Begin
x:=TPlugIn.Create;
x.Handle:= Module;
x.PType:='DLL';
x.FileName:= FileName;
//x.InitPlugIn:=GetProcAddress(Module, 'InitOperDLL');
//x.OpenDLLForm:=GetProcAddress(Module, 'OpenDLLForm');
//x.InitPlugIn(Application, Screen, PlugInInterface, UserInfor);
FModuleList.Add(X)
//这个应该是这样做的啊, X不会因局部变量而失效吧
Result:=True;
End;
End
Else Begin
Application.MessageBox(PChar('没有找到'+FileName+'文件!'),'系统提示',MB_OK+MB_ICONWarning);
End;
End;


Procedure TPlugInManager.OpenDLLForm(PlugInFile, FormName, FormCaption, PlugInFilePath: String);
Var
I: integer;
X: TPlugIn;
Begin
If (FModuleList.Count<=0) and (PlugInFilePath<>'') Then
If LoadingDLL(PlugInFilePath)=False Then
Begin
Application.MessageBox(PChar('加载'+PlugInFilePath+'插件失败,不能开展业务!'),'系统提示',MB_OK+MB_ICONINFORMATION);
exit;
End;

For I:=0 To Self.FModuleList.Count-1 Do //当FModuleList加入TPlugIn对象后,Self.FModuleList.Count的值变得很大。搞不清为什么
begin
X:=TPlugIn(Self.FModuleList.Items);
If X=Nil Then Exit;
X.FileName:=PlugInFilePath
//这里报错,访问地址出错,想不明白,帮我分析一下
If (X.FileName=PlugInFilePath) and (X.PType='DLL') Then
begin
If (PlugInFilePath<>'') and (PlugInFilePaths.IndexOf(PlugInFilePath)<0) Then
LoadingDLL(PlugInFilePath);
isExists:=True;
X.OpenDLLForm(FormName, FormCaption)
//打开DLL中窗体
Break;
End;
End;
End;
 
我用你的程序,没有遇到问题。代码如下(修正了一些明显的错误):

Type
TPlugIn=Class(TObject)
Private
Name: String;
Caption: String;
Handle: HModule;
PType: String;
FileName: String;
End;

Type
TPlugInManager=Class(TObject)
Private
FName: String;
PlugInLibraryDir: String;
FModuleList: TList;
Public
Property Name: String Read FName Write FName;
Function LoadingDLL(FileName: String): Boolean;
Procedure OpenDLLForm(PlugInFile, FormName, FormCaption, PlugInFilePath: String);
constructor Create;
End;

constructor TPlugInManager.Create;
begin
FModuleList:=TList.Create;
end;

Function TPlugInManager.LoadingDLL(FileName: String): Boolean;//加载DLL文件
Var
Module: HMODULE;
x: TPlugIn;
Begin
Result:=False;
if FileExists(FileName) Then
Begin
Module:=0;
Try
Module:=LoadLibrary(PChar(FileName));
Except
on E: Exception do
Begin
MessageBox(Application.Handle, pchar(E.Message), Pchar(Application.Title), MB_OK + MB_ICONERROR);
Module:=0;
End;
End;
If Module>0 then
Begin
x:=TPlugIn.Create;
x.Handle:= Module;
x.PType:='DLL';
x.FileName:= FileName;
FModuleList.Add(X)
//应该是这样做的
Result:=True;
End;
End
Else Begin
Application.MessageBox(PChar('没有找到'+FileName+'文件!'),'系统提示',MB_OK+MB_ICONWarning);
End;
End;

Procedure TPlugInManager.OpenDLLForm(PlugInFile, FormName, FormCaption, PlugInFilePath: String);
Var
I: integer;
X: TPlugIn;
Begin
If (FModuleList.Count<=0) and (PlugInFilePath<>'') Then
If LoadingDLL(PlugInFilePath)=False Then
Begin
Application.MessageBox(PChar('加载'+PlugInFilePath+'插件失败,不能开展业务!'),'系统提示',MB_OK+MB_ICONINFORMATION);
exit;
End;

For I:=0 To FModuleList.Count-1 Do //加入TPlugIn对象后,FModuleList.Count=1
begin
X:=TPlugIn(FModuleList.Items);
If X=Nil Then Exit;
X.FileName:=PlugInFilePath
//这里OK
If (X.FileName=PlugInFilePath) and (X.PType='DLL') Then
begin
//If (PlugInFilePath<>'') and (PlugInFilePaths.IndexOf(PlugInFilePath)<0) Then
// LoadingDLL(PlugInFilePath);
//isExists:=True;
//X.OpenDLLForm(FormName, FormCaption)
//打开DLL中窗体
Break;
End;
End;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
with TPlugInManager.Create do
begin
OpenDLLForm('D:/DemoATP.dll','saa','adfasdf123','D:/DemoATP.dll');
end;
end;

我怀疑你在别的地方将创建好的TPlugIn对象又释放掉了,要不然就在FModuleList列表中
加入了非TPlugIn对象的元素。不过,从FModuleList.Count变得很大的现象上看来,你似乎
是不小心释放了FModuleList,否则它的信息不会变得那么混乱。
 
多人接受答案了。
 
后退
顶部