关于在DLL中调用TXMLDocument时出错的问题! Delphi / Windows SDK/APIhttp://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
明白?