Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Fehler nach freigeben von DLL (https://www.delphipraxis.net/90751-fehler-nach-freigeben-von-dll.html)

gsh 23. Apr 2007 10:51

Datenbank: MySQL • Version: 5.0 • Zugriff über: mysql.pas - libmysql.dll

Fehler nach freigeben von DLL
 
Hi DPler

Ich kämpfe gerade mit einem schwierigen Problem:

Meine Programmstruktur:
Exe -> Datenbank.dll -> libmysql.dll -> MySQL Datenbank

Jetzt hab ich das Problem das wenn ich eine Abfrage durchführe und dann danach das Programm beende dann bekomm ich eine AV und danach einen Runtime Error. :wall:
So wenn ich keine Abfrage durchführe dann kommt beim beenden kein fehler.
Und der Fehler kommt auch nur wenn ich die Datenbank.dll beim beenden freigebe.
Die Datenbank.dll kann die libmysql.dll aber ohne probleme freigeben nur die exe darf die datenbank.dll nicht freigeben

So jetzt hab ich natürlich debuggt und aber leider ziemlich erfolglos da der fehler erst nach dem Appliaction.Run; auftritt und ich somit nicht wirklich debuggen kann.
Die Datenbank.dll kann ich auch nicht debuggen weil diese zu dem Zeitpunkt nichts tut.

Ich bin mir ganz sicher das auf die DLL nach dem freigeben NICHT mehr zugegriffen wird.


Habt ihr eine Idee bei diesem Merkwürdigen Problem? Liegt es vllt. an der libmysql?

mkinzler 23. Apr 2007 10:54

Re: Fehler nach freigeben von DLL
 
Gibst du die Queries wieder frei?

gsh 23. Apr 2007 11:00

Re: Fehler nach freigeben von DLL
 
jo zuerst
mysql_real_query
dann hol ich mir die ganzen daten
und dann mysql_free_result

gsh 24. Apr 2007 18:02

Re: Fehler nach freigeben von DLL
 
*push* :duck:

gsh 26. Apr 2007 13:03

Re: Fehler nach freigeben von DLL
 
*push²*

SirThornberry 26. Apr 2007 13:06

Re: Fehler nach freigeben von DLL
 
sieht für mich so aus als ob bei der Communikation mit deiner DLL der Speicher etwas "verwurschtelt" wird und dann kracht es später wenn versucht wird ordentlich frei zu geben (sozusagen ein Folgefehler). Aber ohne Quelltexte ist das nur Vermutung. Kommt der Fehler auch wenn du in deiner Datenbank.dll nicht auf mysql sachen zugreifst?

gsh 26. Apr 2007 13:35

Re: Fehler nach freigeben von DLL
 
Zitat:

Zitat von SirThornberry
Kommt der Fehler auch wenn du in deiner Datenbank.dll nicht auf mysql sachen zugreifst?

Ne ich muss eine mysql abfrage machen damit dann am schluß der fehler kommt

//edit: ich hab jetzt des auch getestet ob das handle und der proedure einsprungspunkt sich während des programmes geändert hat ... aber das handle und die porcedure adresse ist genau die gleiche wie am ende (wo des dann freigegeben wird) vom programm.

b1zZ 26. Apr 2007 13:55

Re: Fehler nach freigeben von DLL
 
Hatte heute auch ein ähnliches Problem, bei mir war die Lösung, dass ich einfach vergessen hatte einen Memory Manager anzugeben.
Weiss nicht ob dich das jetzt weiter bringt.

RavenIV 26. Apr 2007 16:12

Re: Fehler nach freigeben von DLL
 
Wenn Du von der exe zur dll oder andersrum Strings weitergibst, dann musst du den sharemem einbinden in beide dpr-files. Wichtig ist, dass dies bei den uses an erster Stelle steht.

Oder Du verwendest nur ShortStrings (z.B. str[50]).

Siehe auch die verschiedenen DLL-Tutorials.
Mindestens eines findest Du hier in der DelphiPraxis.

gsh 26. Apr 2007 16:23

Re: Fehler nach freigeben von DLL
 
Zitat:

Zitat von b1zZ
Hatte heute auch ein ähnliches Problem, bei mir war die Lösung, dass ich einfach vergessen hatte einen Memory Manager anzugeben.
Weiss nicht ob dich das jetzt weiter bringt.

wie kann ich den einstellen? was macht des für einen unterschied?

Zitat:

Zitat von RavenIV
Wenn Du von der exe zur dll oder andersrum Strings weitergibst, dann musst du den sharemem einbinden in beide dpr-files. Wichtig ist, dass dies bei den uses an erster Stelle steht.

Oder Du verwendest nur ShortStrings (z.B. str[50]).

Siehe auch die verschiedenen DLL-Tutorials.
Mindestens eines findest Du hier in der DelphiPraxis.

Ich weiß das man keine Strings verwenden sollte. Ich verwende auch ganz sicher keiner. hab sogar extra nochmal nachgeschaut

RavenIV 26. Apr 2007 16:27

Re: Fehler nach freigeben von DLL
 
Zitat:

Zitat von gsh
Ich weiß das man keine Strings verwenden sollte. Ich verwende auch ganz sicher keiner. hab sogar extra nochmal nachgeschaut

Bau trotzdem den sharemem ein. Es schadet ja nicht.

gsh 26. Apr 2007 16:40

Re: Fehler nach freigeben von DLL
 
nein weil ich dann nur noch delphi dlls unterstützen kann
ich will aber in dieser hinsicht unabhängig bleiben

hoika 26. Apr 2007 19:38

Re: Fehler nach freigeben von DLL
 
Hallo,

wenn du ShortString verwendest,
geht es auch ohne sharemem.


Heiko

gsh 26. Apr 2007 20:42

Re: Fehler nach freigeben von DLL
 
ich verwende nur PChar

gsh 27. Apr 2007 18:02

Re: Fehler nach freigeben von DLL
 
*push*

gsh 28. Apr 2007 11:24

Re: Fehler nach freigeben von DLL
 
Ich hab was neues heraus gefunden.
Durch // und viel testen :mrgreen:

jetzt bin ich draufgekommen das in der Datenbank.dll eine Zeile drinnen ist wenn ich sie weg tuhe (mit //) dann gibt es beim beenden keinen fehler. und zwar:
Delphi-Quellcode:
SetLength(DataArray^, mysql_num_fields(MySQL_myRes));
so jetzt hab ich des auch mit
Delphi-Quellcode:
SetLength(DataArray^, 1);
getestet das ich mysql als fehler ausschließen kann und siehe da an dieser Zeile scheitert es.

ABER mein Problem ist die Frage warum, denn:
-Es wird an dieser Stelle kein Fehler ausgelöst
-SetLength(DataArray^, 0); funktioniert :wall:

DatenArray ist vom Typ PDataArray.
Delphi-Quellcode:
PDataArray = ^TDataArray;
  TDataArray = array of PChar;
Dieses Array ist in der Exe vorhanden und wird der DLL als Parameter übergeben

Die Daten werden RICHTIG an die Anwendung geschickt. Aber beim beenden kommt dann der Fehler :wall: :gruebel: :wall: :gruebel: :wall:

gsh 29. Apr 2007 17:26

Re: Fehler nach freigeben von DLL
 
*push*

hoika 30. Apr 2007 07:24

Re: Fehler nach freigeben von DLL
 
Hallo,

Ein SetLength erzeugt u.U. einen neuen Pointer (ReAlloc),
wahrscheinlich ist der Pointer im Daten-Segment der Dll
(?? lange her, das mit Dll bei mir).

Warum machst du das SetLength nicht vor dem DLL-Aufruf ?
Falls die Länge nicht bekannt ist, nimmt halt ne "grosse" Zahl.

Heiko

gsh 30. Apr 2007 08:12

Re: Fehler nach freigeben von DLL
 
Zitat:

Zitat von hoika
Ein SetLength erzeugt u.U. einen neuen Pointer (ReAlloc),
wahrscheinlich ist der Pointer im Daten-Segment der Dll
(?? lange her, das mit Dll bei mir).

Der Pointer wird von der exe in die dll übergeben und die größe vom Array wird ja richtig gesetezt. Nur das Programm stürtzt aber nach dem freigeben der DLL ab.
Ich versteh einfach nicht wieso :wall: Da gibt es ja eigentlich keinen Zusammenhang oder?

Zitat:

Zitat von hoika
Warum machst du das SetLength nicht vor dem DLL-Aufruf ?
Falls die Länge nicht bekannt ist, nimmt halt ne "grosse" Zahl.

nein ist nicht bekannt.
eine große zahl nehmen ... ganz sicher nicht. den diese Anwendung soll schnell laufen und das ist eine überhaupt nicht saubere lösung

hoika 30. Apr 2007 08:19

Re: Fehler nach freigeben von DLL
 
Hallo,

Ein ReAlloc erzeugt unter Umständen einen neuen Pointer
und der alte wird nicht mehr verwendet.
Vielleicht solltest du bei der Übergabe ein Pointer auf einen PChar
nehmen statt das PChar selber.

Der Zusammenhang:
Tja, Dlls.
Mache mal zum Test ein SetLength vor DLL-Aufruf
mit einem grösseren Werte also in der DLL gemacht wird.
Dann verringert das DLL-SetLength den Speicher nur,
ReAlloc sollte nicht aufgerufen werden.


Zu "grosser Wert".
In der DLL muss eh Speicher angefordert werden,
wei viel hängt wovon ab ?
Das man einer Funktion ein PChar + dessen Grösse übergeben muss
ist doch nichts angewöhnliches.
Wenn ich z.B. eine API-Funktion für Pfade benutzen will,
nehme ich MAX_PATH als Grösse des PChar,
obwohl ich vielleicht kleiner Pfade zurückbekomme.


Heiko
PS:
MS (jaja, genau die) hatten mal in einer alten Word (2.0 für Dos)
auch so nen ReAlloc-Fehler drin, der "ab- und zu" zum Absturz
des Programms geführt hatte.
Das stand mal in nem C-Buch bei ReAlloc drin.

gsh 30. Apr 2007 08:25

Re: Fehler nach freigeben von DLL
 
Zitat:

Zitat von hoika
Ein ReAlloc erzeugt unter Umständen einen neuen Pointer
und der alte wird nicht mehr verwendet.
Vielleicht solltest du bei der Übergabe ein Pointer auf einen PChar
nehmen statt das PChar selber.

Ich übergebe ein Array von PChar als Paremter und die Anwendung muss dann die Daten aus dem Array auslesen können. (was es auch kann) also kann es ja gar nicht sein das ein neuer pointer erstellet wird da ja die Exe mit dem "alten" immernoch auf die daten zugreifen kann

hoika 30. Apr 2007 09:29

Re: Fehler nach freigeben von DLL
 
Ja,

das ist eben verwunderlich.
Probier doch mal das SetLength mit "grossem Wert"
mal aus, dann hast du zumindestens ne Notlösung.


Heiko

gsh 30. Apr 2007 09:50

Re: Fehler nach freigeben von DLL
 
ja mit dieser lösung funktioniert es zwar ... aber damit geb ich mich nicht zufrieden ...

ich hab jetzt außerdem endeckt des es egal ist ob ich die DLL freigebe und wieder lade und wieder freigeben ...

Das Programm bringt nur den Fehler wenn:
-In der DLL die Größe (mit SetLength) vom DatenArray verändert wird.
-Die Dll irgendwann mal freigegeben wird.
-Das Programm beendet wird (erst wenn der Ausführungspunkt hinter dem Appliacation.Run; ist tritt der Fehler auf)

Wenn eins davon fehlt dann tritt der Fehler nicht auf

:wall: :wall: :wall:

hoika 30. Apr 2007 09:55

Re: Fehler nach freigeben von DLL
 
Hallo,

was passiert, wenn du nach Benutzung der Daten
ein SetLength(0) machst, also die Sache zurücksetzt ?


Heiko

gsh 30. Apr 2007 10:05

Re: Fehler nach freigeben von DLL
 
Cool jetzt kommt der Fehler nicht mehr :-D

So jetzt ist nur noch die Frage warum
Kann es daran liegen?:
Delphi-Quellcode:
  MySQL_myRow := mysql_fetch_row(MySQL_myRes);
  SetLength(DataArray^, mysql_num_fields(MySQL_myRes));
  for I := 0 to Length(DataArray^)-1 do
  begin
    DataArray^[I] := MySQL_myRow[I]; //<-- hier
  end;
//edit: aja des ist der Code in der DLL

hoika 30. Apr 2007 12:14

Re: Fehler nach freigeben von DLL
 
Hallo,

nein *hoff* ;)

Hast du den Coe mal mit memproof geprüft ?
Es kann sein, dass das SetLength(0) ein mem leak erzeugt.

Das SetLength in der DLL biegt bestimmt den Zeiger um (ReAlloc),
das SetLength(0) sorgt dafür, dass ein Free nichts mehr machen muss.

Ansonsten: Problem #12345 gelöst, weiter zu Problem #12346 ... ;)


Heiko

gsh 30. Apr 2007 12:24

Re: Fehler nach freigeben von DLL
 
Zitat:

Zitat von hoika
Hast du den Coe mal mit memproof geprüft ?
Es kann sein, dass das SetLength(0) ein mem leak erzeugt.

nein aber mit ReportMemoryLeaksOnShutdown:=true; und der meckert a mal nicht


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:37 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