AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Warper-Class und Ungültige Zeigeroperation
Thema durchsuchen
Ansicht
Themen-Optionen

Warper-Class und Ungültige Zeigeroperation

Offene Frage von "theomega"
Ein Thema von theomega · begonnen am 16. Sep 2003 · letzter Beitrag vom 18. Sep 2003
Antwort Antwort
Benutzerbild von theomega
theomega

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

Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 13: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
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#2

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 13:48
Zitat:
function dll_fieldbyname(name:pchar):TField;
Das PChar ist schon mal gut und erspart dir die Unit ShareMem. Aber diesen Vorteil machst du gleich wieder zu nichte, indem du TField zurücklieferst.
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 13:50
hi,

TDLLQuery ist im Hauptprogramm eine Klasse, die so nur eine Typ-Definition ist (ähnlich wie ein Record).

Um nun das ganze nutzen zu können mußt du, bevor du irgendwas anderes damit machst, erstmal eine Instanz erzeugen.

Code:
  :
  :
  QRMain := TDLLQuery.create;
  :
  :
Jetzt kannst du damit arbeiten. Zum abschluß, wenn du die Instanz nicht mehr brauchst solltest du noch QRMain.free aufrufen, damit der Speicher den das Objekt verbraucht, wieder freigegeben wird.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

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

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 14:18
@Ghostwalker: bringt leider nichts!
@jbg: ich bekomme aber das Ergebnis geliefert, kann es trotzdem daran liegen?

Ich habe jetzt oben den Code mal so geändert, das Create und Destory belegt werden!

Grüße
TO
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

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

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 20:22
Weiß den keiner eine Lösung? Wann zeigt Delphi überhaupt den Fehler normalerweise an? Wo kann ich suchen?

Grüße
TO
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#6

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 20:54
Zitat von theomega:
Wann zeigt Delphi überhaupt den Fehler normalerweise an?
Delphi zeigt diesen Fehler an, wenn du einen Zeiger dereferenzierst, der ins Nirvana zeigt. Das sagt dir aber auch die Fehlermeldung.

Zitat:
Wo kann ich suchen?
Überall und nirgends. Das ist nun mal der Fluch von Zeigern.


Hast du es schon mal mit ShareMem probiert, oder anstatt einer DLL ein Package zu nehmen?
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 16. Sep 2003, 22:42
Hi,

hab da noch was entdeckt. Du gibst aus einer DLL ein Object (TField) zurück (GetFieldbyName). Das funktioniert aber nicht mit DLL's, da sie einen eigenen Speicherbereich nutzen, auf den das Hauptprogramm nicht zugreifen kann (mal etwas grob umschrieben).

Entwerder du machst wirklich ein Package draus (mal nach dem Stichwort dynamische Packages suchen). Oder du gibst die relevanten Infos des TField-Objectes einzeln zurück und generierst im Hauptprogramm ein TField daraus (mal so auf die schnelle gedacht).

Werd mir das Morgen noch mal genauer angugen
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

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

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 17. Sep 2003, 11:20
Es funktioniert ja aber alles. Ich komme problemlos an die Daten des Felds heran. Kann also eigentlich nicht daran liegen oder?
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Warper-Class und Ungültige Zeigeroperation

  Alt 18. Sep 2003, 06:53
Na..so problemlos wohl nicht, sonst gäbs keine Fehlermeldung.

Wenn du das Programm ohne IDE laufen läßt wirst du auch feststellen das das Progi beendet wird.

Du mußt dir eine DLL, was die Speicherverwaltung betrifft, vorstellen wie ein richtiges Hauptprogramm. Sie besitzt einen eigenen Speicherbereich, eine eigene VMT usw. auf die ein anderes Programm nicht zugreifen kann.

Folglich kennt dein Hauptprogramm das TField-Objekt aus deiner DLL nicht. Das du trotzdem an die Daten kommst ist reiner Zufall (hängt wohl auch von der Speicherbelegung und dem BS ab).
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz