| Autor |
Beitrag |
Danny87
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Di 21.11.06 04:43
Hey Leute,
ich habe in einer DLL die Prozedur:
lib0005.dll 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| procedure ViewPlanets(sSystem : string; FMysql : TMysqlClient; frmMain : TForm); stdcall; var FResult : TMysqlResult; ex : boolean; i : integer; sHint : string; imgMyImage : TImage; begin FResult := FMysql.query('select * from planeten where system ='+ QuotedStr(sSystem),true,ex); for i:=0 to FResult.RowsCount -1 do begin imgMyImage := frmMain.FindComponent('imgPlanet'+IntToStr(i+1)) as TImage; imgMyImage.Picture.LoadFromFile(FResult.FieldValueByName('pic')); with FResult do begin sHint := 'Name: '+FieldValueByName('planeten')+#10#13+ 'Typ: '+FieldValueByName('typ')+#10#13+#10#13+ 'Bevölkerung: '+FieldValueByName('bevolkerung')+#10#13+ 'Arbeitslose: '+FieldValueByName('arbeitslose')+#10#13+#10#13+ 'Anzahl Gebäude: '+FieldValueByName('gebaude')+#10#13+ 'Anzahl Schiffe: '+FieldValueByName('schiffe'); end; imgMyImage.Hint := sHint; FResult.Next; end;
if FResult <> nil then FResult.Free; end; |
Aber beim Aufrufen der Prozedur ich bekomme immer einen "Invalid class typecast" bei der markierten Codezeile.
Wisst ihr vielleicht woran das liegt und wie ich das beheben kann?
Danke
//EDIT: Bevor ihr fragt, was ich denn schon alles versucht habe: Ich habe versucht frmMain als var zu übergeben.
Also
Delphi-Quelltext 1:
| procedure ViewPlanets(sSystem : string; FMysql : TMysqlClient; var frmMain : TForm); stdcall; |
was allerdings beim Aufruf der Prozedur mit
Delphi-Quelltext 1:
| ViewPlanets(cbCurrentSystem.Items.Strings[cbCurrentSystem.ItemIndex],FMysql,frmMain); |
den Fehler
| Zitat: | | Types of actual and formal var parameters must be identical |
brachte.
Gruss
Daniel
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Di 21.11.06 10:58
Hat wirklich keiner eine Ahnung?
(Sry, ich weiß, dass pushen eigentlich erst nach 24 std erlaubt is, aber ich sollte das heute noch fertig machen)
|
|
Popov
      
Beiträge: 1655
Erhaltene Danke: 13
WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
|
Verfasst: Di 21.11.06 11:35
Bau mal diese Abfrage ein:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| ... for i:=0 to FResult.RowsCount -1 do begin if rmMain.FindComponent('imgPlanet'+IntToStr(i+1)) is TImage then begin imgMyImage := frmMain.FindComponent('imgPlanet'+IntToStr(i+1)) as TImage; end else begin MessageDlg('Fehler beim Auffinden einer Komponente', mtError, [mbOK], 0); Exit; end;
imgMyImage.Picture.LoadFromFile(FResult.FieldValueByName('pic'));
... |
Sag bescheid was rauskommt.
_________________ Popov
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 21.11.06 11:42
oder für Debugzwecke die Klasse ausgeben:
Delphi-Quelltext 1:
| ShowMessage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName); |
Edit: Evtl findet die Routine die Komponente gar nicht.
Delphi-Quelltext 1: 2:
| if frmMain.FindComponent('imgPlanet'+IntToStr(i+1))=NIL then raise Exception.CreateFmt('Komponente %s nicht gefunden!',['imgPlanet'+IntToStr(i+1)]); |
Cu,
Udontknow
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Di 21.11.06 17:52
Hi,
ich schreib einfach mal überall, was ich für ne Meldung bekomme.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| ... for i:=0 to FResult.RowsCount -1 do begin if frmMain.FindComponent('imgPlanet'+IntToStr(i+1)) is TImage then begin imgMyImage := frmMain.FindComponent('imgPlanet'+IntToStr(i+1)) as TImage; end else begin MessageDlg('Fehler beim Auffinden einer Komponente', mtError, [mbOK], 0); Exit; end;
imgMyImage.Picture.LoadFromFile(FResult.FieldValueByName('pic'));
... |
Da bekomme ich die Meldung "Fehler beim Auffinden einer Komponente".
Delphi-Quelltext 1:
| ShowMessage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName); |
Hier steht in der MessageBox "TImage".
Delphi-Quelltext 1: 2:
| if frmMain.FindComponent('imgPlanet'+IntToStr(i+1))=NIL then raise Exception.CreateFmt('Komponente %s nicht gefunden!',['imgPlanet'+IntToStr(i+1)]); |
Hier gibts keine Meldung.
Das verwirrt mich doch schon sehr, muss ich sagen...
Bei der Abfrage
Delphi-Quelltext 1:
| if frmMain.FindComponent('imgPlanet'+IntToStr(i+1)) is TImage then |
meint er es sei kein TImage, aber bei
Delphi-Quelltext 1:
| ShowMessage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName); |
zeigt er als Klassennamen "TImage" an...
Gruss
Daniel
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Do 23.11.06 11:22
Habt Ihr sonst noch Ideen? Ich bin echt der verzweiflung nahe^^ 
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Do 23.11.06 11:34
Ehrlich gesagt, bin ich in DLLs nicht so bewandert, aber vielleicht hat es was damit zu tun. Wurde denn DLL und Hauptprogramm im selben Compiler erstellt? Was ist mit ShareMem (siehe Hilfe), wird das genutzt?
Cu,
Udontknow
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Do 23.11.06 13:08
Jep. Alles im selben Compiler und mit Hilfe von ShareMem gehts auch nicht.
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Do 23.11.06 14:43
Und du hast nicht irgendwie eine TImage-Klasse selber gebastelt, sondern wir sprechen hier von der in der Unit ExtCtrls definierten Klasse, ja?
Ich bin ratlos...
Cu,
Udontknow
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Do 23.11.06 15:34
Es liegt an den is- und as-Operatoren. Die funktioniert nicht, wenn man ihn auf Objekte anwendet, die in einem anderen Executable (egal ob EXE oder DLL) erzeugt wurden. Die Delphi-Laufzeitumgebung erzeugt für jede DLL bzw. EXE eine eigene Klassenregistry, in der die Laufzeit-Typinformationen für die bekannten Klassen gespeichert werden. Wenn du in der DLL is oder as auf ein Objekt anwendest, schaut der in der Klassenregistry der DLL nach - dein TImage ist aber von der Exe erzeugt worden, die ihre eigene Klassenregistry hat. Deswegen liefert wird die Klasse nicht gefunden, is liefert immer false zurück und as wirft eine Exception.
Du hast zwei Möglichkeiten, um dieses Problem herum zu kommen:
1) statt einer DLL ein Package (BPL) bauen. Packages verwenden die Package-Registry des Hauptprogramms, so dass is und as funktionieren. Packages kann man analog zu DLLs mit LoadPackage und UnloadPackage zur Laufzeit laden und entladen.
2) Du verzeichtest auf is und as und prüfst gegen den Klassennamen und verwendest statische Casts:
Delphi-Quelltext 1: 2: 3: 4:
| if frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName = 'TImage' then begin imgMyImage := TImage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1))); end; |
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
Zuletzt bearbeitet von Stefan.Buchholtz am Do 23.11.06 15:49, insgesamt 1-mal bearbeitet
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Do 23.11.06 16:16
Aha, wieder was gelernt. Funktioniert denn die methode InheritsFrom dann auch nicht wie erwartet?
Cu,
Udontknow
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Do 23.11.06 16:25
Udontknow hat folgendes geschrieben: | | Aha, wieder was gelernt. Funktioniert denn die methode InheritsFrom dann auch nicht wie erwartet? |
Soweit ich weiss nicht.
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Do 23.11.06 16:37
Danke schonmal, aber...
Das mit den Packages versteh ich nciht so ganz und wenn ichs mit nem statischen Cast mache, bekomme
ich die Fehlermeldung:
| Colony Trader hat folgendes geschrieben: | | Access violation at address 0059F067 in module 'lib0005.dll'. Read of address 00000008 |
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Do 23.11.06 17:45
Die Zugriffsverletzung ist höchstwahrscheinlich ein Zugriff auf nil. Bist du sicher, dass dein FindComponent immer etwas zurückliefert? Wenn nein, solltest du bei der Überprüfung des Klassennamens vorher auf nil testen. Bei is ist das ja nicht nötig.
Also so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var tmpComp: TComponent; begin ... tmpComp := frmMain.FindComponent('imgPlanet'+IntToStr(i+1)); if Assigned(tmpComp) and (tmpComp.ClassName = 'TImage') then begin imgMyImage := TImage(tmpComp); end; ... end; |
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Sa 25.11.06 06:07
Ich hab die Prozedur jetzt mal so geändert:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| procedure ViewPlanets(sSystem : string; FMysql : TMysqlClient; frmMain : TForm); stdcall; var FResult : TMysqlResult; ex : boolean; i : integer; sHint, sDummy : string; imgMyImage : TImage; tmpComp : TComponent; begin FResult := FMysql.query('select * from planeten where system ='+ QuotedStr(sSystem),true,ex); for i:=0 to FResult.RowsCount -1 do begin tmpComp := frmMain.FindComponent('imgPlanet'+IntToStr(i+1)); if Assigned(tmpComp) and (tmpComp.ClassName = 'TImage') then begin imgMyImage := TImage(tmpComp); sDummy := FResult.FieldValueByName('pic'); if FileExists(sDummy) then imgMyImage.Picture.LoadFromFile(sDummy); end;
with FResult do begin sHint := 'Name: '+FieldValueByName('planeten')+#10#13+ 'Typ: '+FieldValueByName('typ')+#10#13+#10#13+ 'Bevölkerung: '+FieldValueByName('bevolkerung')+#10#13+ 'Arbeitslose: '+FieldValueByName('arbeitslose')+#10#13+#10#13+ 'Anzahl Gebäude: '+FieldValueByName('gebaude')+#10#13+ 'Anzahl Schiffe: '+FieldValueByName('schiffe'); end; if imgMyImage <> nil then imgMyImage.Hint := sHint; imgMyImage.Show; FResult.Next; end;
if FResult <> nil then FResult.Free; end; |
Immer wenn er an der markierten Stelle angekommen ist, springt er sofort komplett aus der Schleife (wie bei "break;" und die Access violation-Fehlermedung erscheint.
Wenn ich das if FResult <> nil then FResult.Free; auskommentiere dann
geht er wieder in den Schleifenkopf und FResult.RowsCount ist plötzlich eine Inaccessible Value...
Resultat: Fehlermeldung.
Wenn ichs nicht auskommentier kommt die Fehlermeldung dort ( if FResult <> nil then FResult.Free;).
Gruss
Daniel
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: So 26.11.06 10:55
Woran könnte das jetzt liegen und wie kann ich das beheben?
(oder anders gesagt: [nachobenpush]  )
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Mo 27.11.06 15:17
Danny87 hat folgendes geschrieben: | Immer wenn er an der markierten Stelle angekommen ist, springt er sofort komplett aus der Schleife (wie bei "break;" und die Access violation-Fehlermedung erscheint.
Wenn ich das if FResult <> nil then FResult.Free; auskommentiere dann
geht er wieder in den Schleifenkopf und FResult.RowsCount ist plötzlich eine Inaccessible Value...
Resultat: Fehlermeldung.
Wenn ichs nicht auskommentier kommt die Fehlermeldung dort (if FResult <> nil then FResult.Free;).
|
Hast du ShareMem eingebunden? Wenn du ein neues Bild in das Image lädst, , wird wahrscheinlich der alte Inhalt des Bildes freigegeben, was in einer DLL nicht erlaubt ist, wenn du ShareMem nicht verwendest.
Wenn es mit ShareMem auch passiert, weiss ich auch nicht mehr weiter...
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Di 28.11.06 10:08
Ahaaaa so kommen wir der Lösung schon immer näher
Mit ShareMem läuft er die Prozedur ganz regulär durch
Allerdings bekomme ich, wenn ich ShareMem benutze beim Beenden die Meldung "Invalid pointer operation" und nen daraus resultierenden "Runtime error".
Ohne ShareMem tritt der Fehler nicht auf.
// EDIT:: Und die Bilder werden trotzdem nicht angezeigt
Gruss
Daniel
Zuletzt bearbeitet von Danny87 am Di 28.11.06 10:15, insgesamt 1-mal bearbeitet
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 28.11.06 10:09
Ist Sharemem sowohl in der Anwendung als auch in der DLL als erste Unit in der DPR eingebunden?
Cu,
Udontknow
|
|
Danny87 
      
Beiträge: 688
Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
|
Verfasst: Di 28.11.06 10:16
Ja. Und BORLNDMM.DLL is im Programmverzeichnis.
Die Bilder werden auch nicht angezeigt
// EDIT:: Den Fehler hab ich grad beseitigt...ich hatte ShareMem doch nicht in der dpr sondern in der Hauptunit vom Program.
Aber die Bilder werden trotzdem noch nicht angezeigt 
|
|