Einzelnen Beitrag anzeigen

Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#1

Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 14:43
Hallo Leute
nachdem ich mit eurer Hilfe zumindest den Fehler in meinem Code gefunden habe, habe ich einen zweiten Anlauf gestartet, meinen Datenbankzugriff in eine DLL auszulagern. Das funktioniert auch schon ganz gut, nur bekomme ich nach jedem Query den Fehler "Ungültige Zeigeroperation". Ich weiß nicht, ob der Fehler von der DLL kommt oder von der Hauptanwendung.

Erstmal der Code:

database.dll:
Delphi-Quellcode:
library database;

uses
  SysUtils,
  Classes,
  IBCustomDataSet,
  IBQuery,
  IBDatabase,
  inifiles,
  dialogs,db,
  IBServices;

{$R *.res}

var qrmain:TIBQuery;
    trmain:TIBTransaction;
    dbmain:TIBDatabase;


procedure dll_initdatabase;
var ini:TIniFile;
begin;
ini := TInifile.create('./config.ini');

try
dbmain := TIBDatabase.Create(nil);
trmain := TIBTransaction.Create(nil);
qrmain := TIBQuery.Create(nil);

dbmain.LoginPrompt := false;
dbmain.DefaultTransaction := trmain;
dbmain.IdleTimer := 0;
dbmain.AllowStreamedConnected := false;

trmain.DefaultDatabase := dbmain;
trmain.Params.Add('concurrency');
trmain.Params.Add('nowait');
trmain.AutoStopAction := saNone;

qrmain.Database := dbmain;
qrmain.Transaction := trmain;
qrmain.CachedUpdates := false;


dbmain.DatabaseName := ini.ReadString('database','databasename','');
dbmain.SQLDialect := ini.ReadInteger('database','sqldialect',3);
dbmain.Params.Text :=
'password='+ini.ReadString('database','password','')+#10#13+
'lc_ctype='+ini.ReadString('database','charset','')+#10#13+
'user_name='+ini.ReadString('database','user_name','');
dbmain.Connected := true;
trmain.Active := true;
finally
  ini.Free;
end;
end;

procedure dll_execquery(str:pchar;passv:boolean);
begin;
qrmain.Close;
qrmain.SQL.Clear;
qrmain.SQL.Add(str);
if (passv) then qrmain.Open
else qrmain.ExecSQL;
end;

procedure dll_commit;
begin;
if trmain.intransaction then trmain.Commit;
Trmain.StartTransaction;
end;

function dll_getinsertid(tab:pchar;fi:pchar):integer;
begin;
dll_execquery(pchar('SELECT max('+fi+') as m FROM '+tab+';'),true);
result := database.qrmain.fieldbyname('m').AsInteger;
end;

procedure dll_next;
begin;
qrmain.Next;
end;

function dll_eof:boolean;
begin;
result := qrmain.Eof;
end;

function dll_recordcount:integer;
begin;
result:= qrmain.RecordCount;
end;

function dll_fieldbyname(name:pchar):TField;
begin;
result:=qrmain.fieldbyname(name);
end;

procedure dll_desinit;
begin;
qrmain.Free;
trmain.Free;
dbmain.Free;
end;


exports dll_initdatabase,dll_execquery,dll_commit,dll_getinsertid,dll_next,dll_eof,dll_recordcount,dll_fieldbyname,dll_desinit;


begin
end.
und im Hauptprogramm:

Erstmal meine Unit mit der Warper-Classe:
Delphi-Quellcode:
unit Udllquery;

interface

uses db;

type TDLLQuery=class
    public
      constructor create;
      destructor destory;
      function fieldbyname(name:string):TField;
      procedure execquery(str:string;passv:boolean);
      procedure commit;
      function recordcount:integer;
      function eof:boolean;
      procedure next;
      function getinsertid(tab:string;fi:string):integer;
end;

implementation


      procedure dll_initdatabase; external 'database.dll';
      function dll_getquery:pointer; external 'database.dll';
      procedure dll_commit; external 'database.dll';
      procedure dll_execquery(str:pchar;passv:boolean); external 'database.dll';
      function dll_fieldbyname(name:pchar):TField; external 'database.dll';
      procedure dll_next;external 'database.dll';
      function dll_eof:boolean;external 'database.dll';
      function dll_recordcount:integer;external 'database.dll';
      function dll_getinsertid(tab:pchar;fi:pchar):integer;external 'database.dll';
      procedure dll_desinit;external 'database.dll';

constructor TDLLquery.create;
begin;
  dll_initdatabase;
  inherited;
end;

destructor TDLLquery.destory;
begin;
  dll_desinit;
  inherited;
end;

procedure TDLLQuery.commit;
begin;
  dll_commit;
end;

procedure TDLLQuery.execquery(str:string;passv:boolean);
begin;
  dll_execquery(pchar(str),passv);
end;

function TDLLQuery.fieldbyname(name:string):TField;
begin;
  result := dll_fieldbyname(pchar(name));
end;

function TDLLQuery.recordcount:integer;
begin;
  result := dll_recordcount;
end;


function TDLLQuery.eof:boolean;
begin;
  result:=dll_eof;
end;

procedure TDLLQuery.next;
begin;
  dll_next;
end;

function TDLLQuery.getinsertid(tab:string;fi:string):integer;
begin;
result:=dll_getinsertid(pchar(tab),pchar(fi));
end;

end.
und mein Zugriff darauf:
Delphi-Quellcode:
var
  Form1: TForm1;
  qrmain:TDllQuery;

procedure TForm1.Button1Click(Sender: TObject);
begin
qrmain := TDLLQuery.create;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
qrmain.execquery('SELECT * FROM sachbuch',true);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
while not qrmain.eof do begin;
    showmessage(qrmain.fieldbyname('sbnr').asstring);
    qrmain.next;
end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
qrmain.Destroy;
end;
Das komische ist: Die Debug-Meldung in meinem Programm wird noch angezeigt: "Query fertig". Erst danach tritt die Exception auf. Eigentlich wird zu der Zeit nirgends Code ausgeführt.

Wer kann mir helfen?

Danke
TO
  Mit Zitat antworten Zitat