在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.

解决方案 »

  1.   

    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);//
      

  2.   

    procedure TForm1.btn1Click(Sender: TObject);
    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;
    前面的没贴全
      

  3.   

    ADOqrey.Fields[2]
    有没有啊?
      

  4.   

    在exe和DLL的工程文件的Use后面添加ShareMem就可以解决了