Autor Beitrag
Danny87
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: Di 21.11.06 04:43 
Hey Leute,

ich habe in einer DLL die Prozedur:
ausblenden 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
ausblenden Delphi-Quelltext
1:
procedure ViewPlanets(sSystem : string; FMysql : TMysqlClient; var frmMain : TForm); stdcall;					

was allerdings beim Aufruf der Prozedur mit
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Di 21.11.06 11:35 
Bau mal diese Abfrage ein:


ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Di 21.11.06 11:42 
oder für Debugzwecke die Klasse ausgeben:

ausblenden Delphi-Quelltext
1:
ShowMessage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName);					


Edit: Evtl findet die Routine die Komponente gar nicht.

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: Di 21.11.06 17:52 
Hi,

ich schreib einfach mal überall, was ich für ne Meldung bekomme. ;)
ausblenden 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".
ausblenden Delphi-Quelltext
1:
ShowMessage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName);					

Hier steht in der MessageBox "TImage".
ausblenden 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
ausblenden Delphi-Quelltext
1:
if frmMain.FindComponent('imgPlanet'+IntToStr(i+1)) is TImage then					

meint er es sei kein TImage, aber bei
ausblenden Delphi-Quelltext
1:
ShowMessage(frmMain.FindComponent('imgPlanet'+IntToStr(i+1)).ClassName);					

zeigt er als Klassennamen "TImage" an... :nut:


Gruss
Daniel
Danny87 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: Do 23.11.06 11:22 
Habt Ihr sonst noch Ideen? Ich bin echt der verzweiflung nahe^^ :cry:
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: Do 23.11.06 13:08 
Jep. Alles im selben Compiler und mit Hilfe von ShareMem gehts auch nicht.
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Do 23.11.06 16:16 
Aha, wieder was gelernt. Funktioniert denn die methode InheritsFrom dann auch nicht wie erwartet?

Cu,
Udontknow
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Do 23.11.06 16:25 
user profile iconUdontknow 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: 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:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: Sa 25.11.06 06:07 
Ich hab die Prozedur jetzt mal so geändert:
ausblenden volle Höhe Delphi-Quelltext
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); // hier springt er komplett aus der schleife
    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; // bei auskommentierung springt er in den schleifenkopf
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: So 26.11.06 10:55 
Woran könnte das jetzt liegen und wie kann ich das beheben?
(oder anders gesagt: [nachobenpush] ;) )
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Mo 27.11.06 15:17 
user profile iconDanny87 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 688

Windows 10 Pro 64bit
Sprachen: HTML, PHP, JavaScript, Delphi || IDE: RAD Studio 10.1 Berlin Starter, WeBuilder
BeitragVerfasst: 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 :(