InterfacedObject对象封装xml放在dll给其他程序调用后内存错(100分)

  • 主题发起人 主题发起人 hophy
  • 开始时间 开始时间
H

hophy

Unregistered / Unconfirmed
GUEST, unregistred user!
下面是整个程序的源代码。程序运行到第73行时报错“Invalid pointer operation”。但XML文件的数值还是能显示到Edit框中。另外退出程序的时候会出内存错。谁能解释是什么原因?怎么解决呢?
001 {客户端project}
002 program TestConfiger;
003
004 uses
005 Windows,
006 SysUtils,
007 Forms,
008 xmldom, XMLIntf, msxmldom, XMLDoc,
009 frm_Main in 'frm_Main.pas' {FrmMain},
010 unt_IHoConfiger in '../unt_IHoConfiger.pas';
011
012 {$R *.res}
013
014 var
015 DllHandle: HModule;
016
017 PGetConfiger: function(I_Owner: TApplication): IHoConfiger; stdcall;
018
019 begin
020 Application.Initialize;
021
022 DllHandle := LoadLibrary('XmlConfiger.dll');
023 if DllHandle = 0 then
024 raise Exception.Create('装载配置文件XmlConfiger.dll失败!');
025
026 @PGetConfiger := GetProcAddress(DllHandle, 'G_GetConfiger');
027 G_IHoConfiger := PGetConfiger(Application); //全局变量定义在unt_IHoConfiger
028
029 G_IHoConfiger.P_LoadFromFile('TestConfiger.xml');
030
031 Application.CreateForm(TFrmMain, FrmMain);
032 Application.Run;
033 end.
034
035
036 {客户端主界面}
037 unit frm_Main;
038
039 interface
040
041 uses
042 unt_IHoConfiger,
043
044 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
045 Dialogs, StdCtrls, Menus;
046
047 type
048 TFrmMain = class(TForm)
049 Label1: TLabel;
050 edit1: TEdit;
051 procedure FormCreate(Sender: TObject);
052 private
053 { Private declarations }
054 public
055 { Public declarations }
056 end;
057
058 var
059 FrmMain: TFrmMain;
060
061 implementation
062
063 {$R *.dfm}
064
065 { TFrmMain }
066
067 procedure TFrmMain.FormCreate(Sender: TObject);
068 var
069 TmpNode: IHoConfigNode;
070 begin
071 TmpNode := G_IHoConfiger.R_RootNode;
072 if TmpNode.R_Name <> '' then
073 edit1.Text := TmpNode.R_Name
074 else
075 edit1.Text := '<null>';
076 end;
077
078 end.
079
080 {接口文件}
081 unit unt_IHoConfiger;
082
083 interface
084
085 uses
086 SysUtils;
087
088 type
089
090 THoConfigEvent = (enuCENodeClose, enuCEFileSave);
091
092 IHoConfigNode = interface
093 ['{63C799C3-2D68-4B10-9F62-0F1BE8FF81C8}']
094 function L_GetName: string;
095 property R_Name: string read L_GetName;
096 end;
097
098 IHoConfiger = interface
099 ['{DCA6A90E-4D31-4A49-A7D5-89E9ED58347E}']
100 procedure P_LoadFromFile(I_FileName: string);
101
102 function L_GetRootNode: IHoConfigNode;
103 property R_RootNode: IHoConfigNode read L_GetRootNode;
104 end;
105
106 var
107 G_IHoConfiger: IHoConfiger;
108
109 implementation
110
111 end.
112
113 {Dll 程序project}
114 library XmlConfiger;
115
116 uses
117 Forms,
118 SysUtils,
119 Classes,
120 unt_THoXmlConfiger in '../unt_THoXmlConfiger.pas',
121 unt_IHoConfiger in '../unt_IHoConfiger.pas';
122
123 {$R *.res}
124
125 function G_GetConfiger(I_Owner: TApplication): IHoConfiger; stdcall;
126 begin
127 Application := I_Owner;
128 Result := THoXmlConfiger.Create(I_Owner);
129 end;
130
131 exports
132 G_GetConfiger;
133
134 begin
135 end.
136
137 {Dll 程序的对象定义}
138 unit unt_THoXmlConfiger;
139
140 interface
141
142 uses
143 unt_IHoConfiger,
144
145 xmldom, XMLIntf, msxmldom, XMLDoc,
146 Classes, SysUtils, Variants;
147
148 type
149 THoXmlConfigNode = class(TInterfacedObject, IHoConfigNode)
150 private
151 F_XMLNode: IXMLNode;
152 public
153 constructor Create(I_XmlNode: IXMLNode);
154
155 function L_GetName: string;
156 property R_Name: string read L_GetName;
157 end;
158
159 THoXmlConfiger = class(TInterfacedObject, IHoConfiger)
160 private
161 F_XMLDoc: TXMLDocument;
162 F_RootNode: IHoConfigNode;
163 public
164 constructor Create(I_Owner: TComponent);
165
166 procedure P_LoadFromFile(I_FileName: string);
167
168 function L_GetRootNode: IHoConfigNode;
169 property R_RootNode: IHoConfigNode read L_GetRootNode;
170 end;
171
172 implementation
173
174 { THoXmlConfiger }
175
176 constructor THoXmlConfiger.Create(I_Owner: TComponent);
177 begin
178 F_XMLDoc := TXMLDocument.Create(I_Owner);
179 end;
180
181 function THoXmlConfiger.L_GetRootNode: IHoConfigNode;
182 begin
183 Result := F_RootNode;
184 end;
185
186 procedure THoXmlConfiger.P_LoadFromFile(I_FileName: string);
187 var
188 TmpRoot: IXMLNode;
189 begin
190 try
191 F_XMLDoc.LoadFromFile(I_FileName);
192 except
193 with F_XMLDoc.XML do
194 begin
195 Add('<?xml version="1.0" encoding="gb2312"?>'); //支持中文
196 Add('<Setting>');
197 Add(' <RootNode>Root</RootNode>');
198 Add('</Setting>');
199 end;
200 F_XMLDoc.Active := true;
201 F_XMLDoc.SaveToFile(I_FileName);
202 F_XMLDoc.LoadFromFile(I_FileName);
203 end;
204
205 TmpRoot := F_XMLDoc.DocumentElement.ChildNodes.FindNode('RootNode');
206 F_RootNode := THoXmlConfigNode.Create(TmpRoot);
207 end;
208
209 { THoXmlConfigNode }
210
211 constructor THoXmlConfigNode.Create(I_XmlNode: IXMLNode);
212 begin
213 F_XMLNode := I_XmlNode;
214 end;
215
216 function THoXmlConfigNode.L_GetName: string;
217 begin
218 Result := F_XMLNode.NodeName;
219 end;
220
221 end.
 
可能程序太长了不好理解,简而言之就是在Dll中用IHoConfiger封装TXMLDocument对象,用IHoConfigNode封装IXMLNode。目的为了让客户端程序只能通过IHoConfiger和IHoConfigNode的接口访问TXMLDocument和IXMLNode。
 
怎么没有人理我?
 
你的程序太长了。我没看,
我觉得你应该在接口变量传递中查找,看看有没有丢东西。
 
其实可以拷贝到Delphi中看看(要去掉行号,可以运行的)。在Delphi里面看不算太长,而且我已经精简过。我已经研究了很久,就是看不出什么原因。
 

Similar threads

后退
顶部