關於在DLL中調用TXMLDocument時出錯的問題! Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiBase/html/delphi_20061218133656127.html
我在dll中使用XML讀取和寫如配置,每次靜態調用完以後都會出現錯誤:Access violation at address 00000000. Read of address 00000000. ,應該是什麼沒有釋放的問題請大家給看看
代碼:
library DoitLib;
uses
SysUtils, xmldom, XMLIntf, MSxmldom, XMLDoc,
Classes, Forms,activex;
{$R *.res}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////GetConfig:讀取配置參數;傳回值:Pchar//////////////////
//////////參數 Section :分組節點;類型:Pchar//////////////////////////////////
//////////參數 Key:配置項節點:類型:Pchar ///////////////////////////////////
/////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
function GetConfig(Section, Key: Pchar): Pchar; stdcall;
var
MyPath: string; //檔案路徑
ConfigFile: TXMLDocument; //設定檔
TheNode: IXMLNode; //臨時儲存節點變數
begin
MyPath := ExtractFileDir(GetModuleName(0)) + '\Config.xml'; //擷取檔案路徑
CoInitialize(nil);
ConfigFile := TXMLDocument.Create(Application); //建立XML
// ConfigFile.DOMVendor := OpenXMLFactory; //指定解析器
ConfigFile.Active := TRUE;
if not FileExists(MyPath) then {//如果檔案不存在} begin
result := Pchar(''); //如果檔案不存在,則返回空
exit;
end
else
ConfigFile.LoadFromFile(MyPath); //如果檔案存在,則從檔案載入內容
TheNode := ConfigFile.DocumentElement; //擷取根節點
if TheNode.ChildNodes.FindNode(Section) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Section) //如果組節點存在,擷取該組節點
else begin
result := Pchar(''); //如果組節點不存在,則返回空
exit;
end;
if TheNode.ChildNodes.FindNode(Key) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Key) //如果配置項節點存在,擷取該配置項節點
else begin
result := Pchar(''); //如果配置項節點不存在,則返回空
exit;
end;
result := Pchar(TheNode.Text);
// ConfigFile.Active := false;
ConfigFile.Free;
CoUninitialize;
end;
function SetConfig(Section, Key, NewValue: Pchar): integer; stdcall;
var
MyPath: string; //檔案路徑
ConfigFile: TXMLDocument; //設定檔
TheNode: IXMLNode; //臨時儲存節點變數
TempRST:INTEGER;
begin
TempRST:=1;
CoInitialize(nil);
MyPath := ExtractFileDir(GetModuleName(0)) + '\Config.xml'; //擷取檔案路徑
try
ConfigFile := TXMLDocument.Create(Application); //建立XML
// ConfigFile.DOMVendor := OpenXMLFactory; //指定解析器
ConfigFile.Active := TRUE;
//設定檔案自動換行
if not FileExists(MyPath) then {//如果檔案不存在} begin
ConfigFile.Version := '1.0';
ConfigFile.Encoding := 'GB2312';
ConfigFile.Options := ConfigFile.Options + [doNodeAutoIndent];
TheNode := ConfigFile.CreateNode('DoitFaxConfig');
ConfigFile.DocumentElement := TheNode;
end
else begin
ConfigFile.LoadFromFile(MyPath); //如果檔案存在,則從檔案載入內容
ConfigFile.Version := '1.0';
ConfigFile.Encoding := 'GB2312';
ConfigFile.Options := ConfigFile.Options + [doNodeAutoIndent];
end;
TheNode := ConfigFile.DocumentElement; //擷取根節點
if TheNode.ChildNodes.FindNode(Section) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Section) //如果組節點存在,擷取該組節點
else
TheNode := TheNode.AddChild(Section); //如果組節點不存在,則建立
if TheNode.ChildNodes.FindNode(Key) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Key) //如果配置項節點存在,擷取該配置項節點
else
TheNode := TheNode.AddChild(Key);
TheNode.Text := NewValue;
ConfigFile.SaveToFile(MyPath);
TempRST:=0;
finally
ConfigFile.Active := false;
ConfigFile.Free;
ConfigFile.Destroy;
CoUninitialize;
result := TempRST;
end;
end;
exports
GetConfig, SetConfig;
begin
end.
library Project1;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,XMLDoc,XMLIntf,activex,Forms,
Classes;
{$R *.res}
function GetConfig(Section, Key: Pchar): Pchar; stdcall;
var
MyPath: string; //檔案路徑
ConfigFile: TXMLDocument; //設定檔
TheNode: IXMLNode; //臨時儲存節點變數
begin
MyPath := ExtractFileDir(GetModuleName(0)) + '\Config.xml'; //擷取檔案路徑
CoInitialize(nil);
ConfigFile := TXMLDocument.Create(Application); //建立XML
// ConfigFile.DOMVendor := OpenXMLFactory; //指定解析器
ConfigFile.Active := TRUE;
if not FileExists(MyPath) then {//如果檔案不存在} begin
result := Pchar(''); //如果檔案不存在,則返回空
exit;
end
else
ConfigFile.LoadFromFile(MyPath); //如果檔案存在,則從檔案載入內容
TheNode := ConfigFile.DocumentElement; //擷取根節點
if TheNode.ChildNodes.FindNode(Section) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Section) //如果組節點存在,擷取該組節點
else begin
result := Pchar(''); //如果組節點不存在,則返回空
exit;
end;
if TheNode.ChildNodes.FindNode(Key) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Key) //如果配置項節點存在,擷取該配置項節點
else begin
result := Pchar(''); //如果配置項節點不存在,則返回空
exit;
end;
result := PChar(TheNode.Text);
// ConfigFile.Active := false;
ConfigFile.Free;
CoUninitialize;
end;
function SetConfig(Section, Key, NewValue: Pchar): integer; stdcall;
var
MyPath: string; //檔案路徑
ConfigFile: TXMLDocument; //設定檔
TheNode: IXMLNode; //臨時儲存節點變數
TempRST:INTEGER;
begin
TempRST:=1;
CoInitialize(nil);
MyPath := ExtractFileDir(GetModuleName(0)) + '\Config.xml'; //擷取檔案路徑
try
ConfigFile := TXMLDocument.Create(Application); //建立XML
// ConfigFile.DOMVendor := OpenXMLFactory; //指定解析器
ConfigFile.Active := TRUE;
//設定檔案自動換行
if not FileExists(MyPath) then {//如果檔案不存在} begin
ConfigFile.Version := '1.0';
ConfigFile.Encoding := 'GB2312';
ConfigFile.Options := ConfigFile.Options + [doNodeAutoIndent];
TheNode := ConfigFile.CreateNode('DoitFaxConfig');
ConfigFile.DocumentElement := TheNode;
end
else begin
ConfigFile.LoadFromFile(MyPath); //如果檔案存在,則從檔案載入內容
ConfigFile.Version := '1.0';
ConfigFile.Encoding := 'GB2312';
ConfigFile.Options := ConfigFile.Options + [doNodeAutoIndent];
end;
TheNode := ConfigFile.DocumentElement; //擷取根節點
if TheNode.ChildNodes.FindNode(Section) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Section) //如果組節點存在,擷取該組節點
else
TheNode := TheNode.AddChild(Section); //如果組節點不存在,則建立
if TheNode.ChildNodes.FindNode(Key) <> nil then
TheNode := TheNode.ChildNodes.FindNode(Key) //如果配置項節點存在,擷取該配置項節點
else
TheNode := TheNode.AddChild(Key);
TheNode.Text := NewValue;
ConfigFile.SaveToFile(MyPath);
TempRST:=0;
finally
ConfigFile.Active := false;
ConfigFile.Free;
ConfigFile.Destroy;
CoUninitialize;
result := TempRST;
end;
end;
exports
GetConfig, SetConfig;
begin
end.
重建立立一個DLL 換成上面代碼試試~~
還是會有那個錯誤,我看不出下面的代碼與上面代碼有那裡不同。
沒什麼哪裡不同 那個DLL本身編譯出錯才是正確的
要做的是讓一個程式調用你寫的DLL
明白?