在exe里调用dll的接口创建一个adoquery,如过不从adoquery里取数据,关闭,释放内存都不会有问题,但是一旦取数据比如用了adoquery.fieldbyname; adoquery.fields;ADOqrey.GetFieldNames。等语句的时候结束时就会报错。错误为:“Invalid pointer operation”(注:exe程序把动态创建的ado改成静态放置一个的时候可以正常),下面是dll的代码:unit uExportDLL;interfaceuses
SysUtils, ADODB, Classes,ActiveX,
//*************************************************************************//
uInterface; // 模块初始化函数
function LinkerCreate: IDBLinker; stdcall;
procedure LinkerDestroy; stdcall;
type
TADOLink = class(TObject)
private
ADOConect: TADOConnection;
FADOList: TList;
public
constructor Create;
destructor Destroy; override;
function GetQuery: Pointer;
procedure KillQuery(P: Pointer);
function ConnecttoDB(aStr: string): Boolean;
procedure KillAllADO;
function IsConnect: Boolean;
function DisConnect: Boolean;
end; TDBLinker = class(TInterfacedObject, IDBLinker)
private
function GetQuery: Pointer;
procedure KillQuery(P: Pointer);
function ConnecttoDB(aStr: string): Boolean;
procedure KillAllADO;
function IsConnect: Boolean;
function DisConnect: Boolean;
public
constructor Create;
end; function CreateDBLinkObject: IDBLinker; stdcall;
implementationuses ComObj;var
_IDBLinker: IDBLinker;
ADOLink: TADOLink;function LinkerCreate: IDBLinker; stdcall;
begin
try
if not Assigned(ADOLink) then
ADOLink := TADOLink.Create;
Result := CreateDBLinkObject;
except
Result := nil;
FreeAndNil(ADOLink);
end;
end;procedure LinkerDestroy; stdcall;
begin
if Assigned(ADOLink) then
begin
ADOLink.Free;
ADOLink := nil;
end; _IDBLinker := nil;
end;function CreateDBLinkObject: IDBLinker;stdcall;
begin
if not Assigned(_IDBLinker) then
begin
_IDBLinker := TDBLinker.Create;
end;
Result := _IDBLinker;
end;{ TDBLinker }
constructor TDBLinker.Create;
beginend;function TDBLinker.ConnecttoDB(aStr: string): Boolean;
begin
Result := False;
if Assigned(ADOLink) then
Result := ADOLink.ConnecttoDB(aStr);
end;function TDBLinker.GetQuery: Pointer;
begin
Result := nil;
if Assigned(ADOLink) then
Result := ADOLink.GetQuery;
end;procedure TDBLinker.KillAllADO;
begin
if Assigned(ADOLink) then
ADOLink.KillAllADO;
end;procedure TDBLinker.KillQuery(P: Pointer);
begin
if Assigned(ADOLink) then
ADOLink.KillQuery(P);
end;function TDBLinker.IsConnect: Boolean;
begin
Result := False;
if Assigned(ADOLink) then
Result := ADOLink.IsConnect;
end;{ TADOAcc }constructor TADOLink.Create;
begin
ADOConect := TADOConnection.Create(nil);
FADOList := TList.Create;
end;destructor TADOLink.Destroy;
begin
KillAllADO;
FADOList.Free;
FADOList := nil;
ADOConect.Free;
ADOConect := nil;
inherited;
end;function TADOLink.ConnecttoDB(aStr: string): Boolean;
begin
if Assigned(ADOConect) then
begin
try
ADOConect.Connected := False;
ADOConect.ConnectionString := aStr;
ADOConect.Connected := True;
Result := ADOConect.Connected;
except
Result := False;
end;
end
else Result := False;
end;//********************************************************//
报错的函数
function TADOLink.GetQuery: Pointer;//取一个ADOQuery的指针地址
var
ADOqry: TADOQuery;
begin
if Assigned(ADOConect) and ADOConect.Connected and Assigned(FADOList) then
begin
ADOqry := TADOQuery.Create(nil);
ADOqry.Connection := ADOConect;
FADOList.Add(ADOqry);
Result := @ADOqry;
end
else Result := nil;
end;procedure TADOLink.KillAllADO;//杀掉所有的ADOQuery
var
i: Integer;
ADOqry: TADOQuery;
begin
if Assigned(FADOList) then
begin
for i := FADOList.Count -1 downto 0 do
begin
ADOqry := FADOList.Items[i];
ADOqry.Close;
ADOqry.Free;
end;
FADOList.Clear;
end;
end;procedure TADOLink.KillQuery(P: Pointer);//杀掉指定的ADOQuery
var
i: Integer;
ADOqry: TADOQuery;
begin
if Assigned(FADOList) then
begin
for i := FADOList.Count -1 downto 0 do
begin
ADOqry := FADOList.Items[i];
if @ADOqry = p then
begin
ADOqry.Close;
ADOqry.Free;
FADOList.Delete(i);
Exit;
end;
end;
end;
end;
//**************************************************************************//
function TADOLink.IsConnect: Boolean;
begin
Result := False;
if Assigned(ADOConect) then
Result := ADOConect.Connected;
end;function TADOLink.DisConnect: Boolean;
begin
Result := True;
if Assigned(ADOConect) then
begin
try
KillAllADO;
ADOConect.Connected := False;
Result := ADOConect.Connected;
except
Result := ADOConect.Connected;
end;
end;
end;function TDBLinker.DisConnect: Boolean;
begin
Result := True;
if Assigned(ADOLink) then
Result := ADOLink.DisConnect;
end;
initialization
CoInitialize(nil);
finalization
CoUninitialize;
end.
SysUtils, ADODB, Classes,ActiveX,
//*************************************************************************//
uInterface; // 模块初始化函数
function LinkerCreate: IDBLinker; stdcall;
procedure LinkerDestroy; stdcall;
type
TADOLink = class(TObject)
private
ADOConect: TADOConnection;
FADOList: TList;
public
constructor Create;
destructor Destroy; override;
function GetQuery: Pointer;
procedure KillQuery(P: Pointer);
function ConnecttoDB(aStr: string): Boolean;
procedure KillAllADO;
function IsConnect: Boolean;
function DisConnect: Boolean;
end; TDBLinker = class(TInterfacedObject, IDBLinker)
private
function GetQuery: Pointer;
procedure KillQuery(P: Pointer);
function ConnecttoDB(aStr: string): Boolean;
procedure KillAllADO;
function IsConnect: Boolean;
function DisConnect: Boolean;
public
constructor Create;
end; function CreateDBLinkObject: IDBLinker; stdcall;
implementationuses ComObj;var
_IDBLinker: IDBLinker;
ADOLink: TADOLink;function LinkerCreate: IDBLinker; stdcall;
begin
try
if not Assigned(ADOLink) then
ADOLink := TADOLink.Create;
Result := CreateDBLinkObject;
except
Result := nil;
FreeAndNil(ADOLink);
end;
end;procedure LinkerDestroy; stdcall;
begin
if Assigned(ADOLink) then
begin
ADOLink.Free;
ADOLink := nil;
end; _IDBLinker := nil;
end;function CreateDBLinkObject: IDBLinker;stdcall;
begin
if not Assigned(_IDBLinker) then
begin
_IDBLinker := TDBLinker.Create;
end;
Result := _IDBLinker;
end;{ TDBLinker }
constructor TDBLinker.Create;
beginend;function TDBLinker.ConnecttoDB(aStr: string): Boolean;
begin
Result := False;
if Assigned(ADOLink) then
Result := ADOLink.ConnecttoDB(aStr);
end;function TDBLinker.GetQuery: Pointer;
begin
Result := nil;
if Assigned(ADOLink) then
Result := ADOLink.GetQuery;
end;procedure TDBLinker.KillAllADO;
begin
if Assigned(ADOLink) then
ADOLink.KillAllADO;
end;procedure TDBLinker.KillQuery(P: Pointer);
begin
if Assigned(ADOLink) then
ADOLink.KillQuery(P);
end;function TDBLinker.IsConnect: Boolean;
begin
Result := False;
if Assigned(ADOLink) then
Result := ADOLink.IsConnect;
end;{ TADOAcc }constructor TADOLink.Create;
begin
ADOConect := TADOConnection.Create(nil);
FADOList := TList.Create;
end;destructor TADOLink.Destroy;
begin
KillAllADO;
FADOList.Free;
FADOList := nil;
ADOConect.Free;
ADOConect := nil;
inherited;
end;function TADOLink.ConnecttoDB(aStr: string): Boolean;
begin
if Assigned(ADOConect) then
begin
try
ADOConect.Connected := False;
ADOConect.ConnectionString := aStr;
ADOConect.Connected := True;
Result := ADOConect.Connected;
except
Result := False;
end;
end
else Result := False;
end;//********************************************************//
报错的函数
function TADOLink.GetQuery: Pointer;//取一个ADOQuery的指针地址
var
ADOqry: TADOQuery;
begin
if Assigned(ADOConect) and ADOConect.Connected and Assigned(FADOList) then
begin
ADOqry := TADOQuery.Create(nil);
ADOqry.Connection := ADOConect;
FADOList.Add(ADOqry);
Result := @ADOqry;
end
else Result := nil;
end;procedure TADOLink.KillAllADO;//杀掉所有的ADOQuery
var
i: Integer;
ADOqry: TADOQuery;
begin
if Assigned(FADOList) then
begin
for i := FADOList.Count -1 downto 0 do
begin
ADOqry := FADOList.Items[i];
ADOqry.Close;
ADOqry.Free;
end;
FADOList.Clear;
end;
end;procedure TADOLink.KillQuery(P: Pointer);//杀掉指定的ADOQuery
var
i: Integer;
ADOqry: TADOQuery;
begin
if Assigned(FADOList) then
begin
for i := FADOList.Count -1 downto 0 do
begin
ADOqry := FADOList.Items[i];
if @ADOqry = p then
begin
ADOqry.Close;
ADOqry.Free;
FADOList.Delete(i);
Exit;
end;
end;
end;
end;
//**************************************************************************//
function TADOLink.IsConnect: Boolean;
begin
Result := False;
if Assigned(ADOConect) then
Result := ADOConect.Connected;
end;function TADOLink.DisConnect: Boolean;
begin
Result := True;
if Assigned(ADOConect) then
begin
try
KillAllADO;
ADOConect.Connected := False;
Result := ADOConect.Connected;
except
Result := ADOConect.Connected;
end;
end;
end;function TDBLinker.DisConnect: Boolean;
begin
Result := True;
if Assigned(ADOLink) then
Result := ADOLink.DisConnect;
end;
initialization
CoInitialize(nil);
finalization
CoUninitialize;
end.
aPointer := FADOCreate.GetQuery; ADOqrey := TADOQuery(aPointer^);
ADOqrey.Close;
ADOqrey.SQL.Text := 'select * from test';
ADOqrey.Open;
ShowMessage(ADOqrey.Fields[0].AsString);
ShowMessage(ADOqrey.Fields[1].AsString);
ShowMessage(ADOqrey.Fields[2].AsString);//执行完这句后报错。即使后面没有语句或者是ADOqrey.close;都回报错 FADOCreate.KillQuery(aPointer);//
var
ADOqrey: TADOQuery;
aPointer: Pointer;
begin
FADOCreate.ConnecttoDB('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\DllTest\dllTest.mdb;Persist Security Info=False');
aPointer := FADOCreate.GetQuery; ADOqrey := TADOQuery(aPointer^);
ADOqrey.Close;
ADOqrey.SQL.Text := 'select * from test';
ADOqrey.Open;
ShowMessage(ADOqrey.Fields[0].AsString);
ShowMessage(ADOqrey.Fields[1].AsString);
ShowMessage(ADOqrey.Fields[2].AsString);//执行完这句后报错。即使后面没有语句或者是ADOqrey.close;都回报错 FADOCreate.KillQuery(aPointer);//
end;
前面的没贴全
有没有啊?