Autor |
Beitrag |
GR-Thunderstorm
      
Beiträge: 206
|
Verfasst: Di 01.11.11 11:32
Hey!
Ich habe mich nach vielen Jahren Delphi-Abstinenz nun doch wieder mit meinem Delphi7 Enterprise auseinander gesetzt und möchte ein kleines Programm schreiben.
Damit es auch übersichtlich bleibt, möchte ich einige Functions / Procedures in eine andere Unit auslagern.
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:
| unit MainUnit;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math, ExtCtrls, Buttons, ComCtrls, Mask, StrUtils;
type TForm1 = class(TForm) Button2: TButton; procedure Button2Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
uses Functions;
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject); var Float: Real; begin Float:=Bessel_1(2.405,100); ShowMessage(FloatToStr(Float)); end;
end. |
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:
| unit Functions;
interface uses Graphics, SysUtils, Math, MainUnit;
implementation
function Factorial_2(Int: Integer) : Extended; begin if (Int <2) then Result := 1 else Result := Int*Factorial_2(Int-2); end;
function Bessel_1(X: Extended; Steps: Integer) : Extended; var i: Integer; PreResult: Real; begin PreResult:=0; for i:=1 to Steps do begin PreResult:= PreResult + Power(-1, i+1 mod 2)*Power(X,i*2-1) / (Power(Factorial_2((i*2)-2),2)*i*2); end;
Result:=PreResult;
end;
end. |
Wenn ich das Programm starten will, springt er in der MainUnit an die Stelle, wo Bessel_1 aufgerufen werden soll und meckert: 'Undeclared identifier: Bessel_1'
Was mache ich denn falsch?
EDIT: Problemstellung hat sich geändert.  Siehe weiter unten.
Zuletzt bearbeitet von GR-Thunderstorm am Mo 07.11.11 22:28, insgesamt 2-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 01.11.11 11:47
Delphi weiß nicht, dass die Funktion für andere Units sichtbar sein soll. 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:
| unit Functions;
interface
uses Graphics, SysUtils, Math, MainUnit;
function Factorial_2(Int: Integer): Extended; function Bessel_1(X: Extended; Steps: Integer): Extended;
implementation
function Factorial_2(Int: Integer): Extended; begin if (Int < 2) then Result := 1 else Result := Int * Factorial_2(Int - 2); end;
function Bessel_1(X: Extended; Steps: Integer): Extended; var i: Integer; PreResult: Real; begin PreResult := 0; for i := 1 to Steps do begin PreResult := PreResult + Power(-1, i + 1 mod 2) * Power(X, i * 2 - 1) / (Power(Factorial_2((i * 2) - 2), 2) * i * 2); end;
Result := PreResult; end;
end. | Nebenbei: Unterstriche in Funktionsnamen sind kein guter Stil. 
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Di 01.11.11 21:41
Danke, das hat funktioniert!
Geht es auch irgendwie, dass ich alle globalen Variablen in eine externe Unit auslagere?
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 01.11.11 21:49
Verwende möglichst niemals globale Variablen. Das ist sehr schlechter Stil, da es die Übersicht enorm verringert...
Du kannst stattdessen z.B. Sachen in Klassen kapseln, je nachdem was du machst.
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Mo 07.11.11 21:37
Soweit so gut, ich wollte eine eigene Klasse erstellen, um in dieser einige Werte berechnen zu lassen.
Hier zunächst der Code:
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: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77:
| type Mue = class private Precision: Integer; Z0: Variant; ffg: Variant; MueIm: Variant; MueRe: Variant;
procedure Assign_ffg(f: Variant); procedure Assign_Z(Z: Variant);
public procedure Create();
property Z: Variant read Z0 write Assign_Z; property f_fg: Variant read ffg write Assign_ffg; property Im: Variant read MueIm; property Re: Variant read MueRe; end;
implementation
uses Functions;
procedure TSensor.LO(Z:Integer); begin Lift:=Z; end;
procedure Mue.Create(); begin Precision:=160; self.Z0:=VarArrayCreate([0,0],VarVariant); self.ffg:=VarArrayCreate([0,0],VarVariant); self.MueIm:=VarArrayCreate([0,0],VarVariant); self.MueRe:=VarArrayCreate([0,0],VarVariant); end;
procedure Mue.Assign_Z(Z: Variant); var Index,i: Integer; f: Extended; begin
f:=Z*Z;
for i:=0 to VarArrayHighBound(Z0,1)-1 do begin if Z > Z0[i] and Z < Z0[i+1] then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision));
end;
procedure Mue.Assign_ffg(f: Variant); var Index,i: Integer; Z: Extended; begin
Z:=sqrt(f);
for i:=0 to VarArrayHighBound(ffg,1)-1 do begin if Z > Z0[i] and Z < Z0[i+1] then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision));
end; |
An besagter Stelle erzeugt mein Programm jedes mal einen Fehler, wenn ich eine Variable vom Typ Mue deklariere und die Create-Funktion aufrufe. Auf diese Weise habe ich allerdings schon etliche Variant-Arrays erstellt und nie gab es Probleme! Muss ich in einer Klasse anders verfahren, um VarArrayCreate anwenden zu können?
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mo 07.11.11 21:45
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Mo 07.11.11 21:57
Das ändert leider nichts.  Jetzt erzeugt er schon bei
Delphi-Quelltext
einen Fehler.
EDIT:
Soeben beschriebenes konnte ich korrigieren, indem ich folgendes gemacht habe:
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: 38: 39: 40:
| type Mue = class private Precision: Integer; Z0: Variant; ffg: Variant; MueIm: Variant; MueRe: Variant;
procedure Assign_ffg(f: Variant); procedure Assign_Z(Z: Variant); procedure SetPrecision(X: Integer);
property Pr: Integer read Precision write SetPrecision;
public constructor Create();
property Z: Variant read Z0 write Assign_Z; property f_fg: Variant read ffg write Assign_ffg; property Im: Variant read MueIm; property Re: Variant read MueRe; end;
implementation
uses Functions;
procedure TSensor.LO(Z:Integer); begin Lift:=Z; end;
constructor Mue.Create(); begin self.Pr:=160; self.Z:=VarArrayCreate([0,0],varVariant); self.ffg:=VarArrayCreate([0,0],varVariant); self.MueIm:=VarArrayCreate([0,0],varVariant); self.MueRe:=VarArrayCreate([0,0],varVariant); end; |
Selbiges wollte ich mit Z machen:
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: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| procedure Mue.SetPrecision(X: Integer); begin Precision:=X; end;
procedure Mue.Assign_Z(Z: Variant); var Index,i: Integer; f: Extended; begin
if Z = VarArrayCreate([0,0],varVariant) then begin Z:=VarArrayCreate([0,0],varVariant); end else begin
f:=Z*Z;
for i:=0 to VarArrayHighBound(Z0,1)-1 do begin if Z > Z0[i] and Z < Z0[i+1] then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision)); end;
end;
procedure Mue.Assign_ffg(f: Variant); var Index,i: Integer; Z: Extended; begin
Z:=sqrt(f);
if f = VarArrayCreate([0,0],varVariant) then begin ffg:=VarArrayCreate([0,0],varVariant); end else begin
for i:=0 to VarArrayHighBound(ffg,1)-1 do begin if Z > Z0[i] and Z < Z0[i+1] then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision));
end;
end; |
Zuletzt bearbeitet von GR-Thunderstorm am Mo 07.11.11 22:20, insgesamt 3-mal bearbeitet
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Mo 07.11.11 22:10
"einen Fehler", das ist ja äußerst präzise und nun weiß jeder, was das sein könnte... 
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Blawen
      
Beiträge: 616
Erhaltene Danke: 33
Win XP, Vista, 7
Delphi 5 Prof., BDS 2006 Prof. RAD Studio XE
|
Verfasst: Mo 07.11.11 22:20
GR-Thunderstorm hat folgendes geschrieben : | Das ändert leider nichts... Precision:=160;
einen Fehler. |
1. Dieser Fehler wird sicher genauer ausgegeben.
2. Vermutlich wird es daran liegen, dass Precision als "Private" deklariert wurde.
_________________ Es kompilert, wir können ausliefern.
Und es kompiliert wieder - das Update ist fertig - bitte 100 Euro
Zuletzt bearbeitet von Blawen am Mo 07.11.11 22:23, insgesamt 1-mal bearbeitet
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Mo 07.11.11 22:22
Zuletzt bearbeitet von GR-Thunderstorm am Mo 07.11.11 22:26, insgesamt 1-mal bearbeitet
|
|
Blawen
      
Beiträge: 616
Erhaltene Danke: 33
Win XP, Vista, 7
Delphi 5 Prof., BDS 2006 Prof. RAD Studio XE
|
Verfasst: Mo 07.11.11 22:25
[OT]Stochern im Nebel  [/OT]
_________________ Es kompilert, wir können ausliefern.
Und es kompiliert wieder - das Update ist fertig - bitte 100 Euro
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Mo 07.11.11 22:27
|
|
Blawen
      
Beiträge: 616
Erhaltene Danke: 33
Win XP, Vista, 7
Delphi 5 Prof., BDS 2006 Prof. RAD Studio XE
|
Verfasst: Mo 07.11.11 22:34
Zitat: | 'Invalid variant operation' |
Ist schon mal eine brauchbare Aussage.
Allerdings wäre es von Vorteil, wenn auch wir wüssten, wie Deine aktuelle "Baustelle" aussieht (QT-Auzug)
_________________ Es kompilert, wir können ausliefern.
Und es kompiliert wieder - das Update ist fertig - bitte 100 Euro
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Mo 07.11.11 22:38
Je nach Art der Ausführung entweder hier:
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:
| constructor Mue.Create(); begin self.Pr:=160; self.Z:=VarArrayCreate([0,0],varVariant); self.ffg:=VarArrayCreate([0,0],varVariant); self.MueIm:=VarArrayCreate([0,0],varVariant); self.MueRe:=VarArrayCreate([0,0],varVariant); end;
procedure Mue.Assign_Z(Z: Variant); var Index,i: Integer; f: Extended; begin
if Z = VarArrayCreate([0,0],varVariant) then begin Z0:=VarArrayCreate([0,0],varVariant); end else begin
f:=Z*Z;
for i:=0 to VarArrayHighBound(Z0,1)-1 do begin if (Z > Z0[i]) and (Z < Z0[i+1]) then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision)); end;
end; |
Oder hier:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| constructor Mue.Create(); begin self.Pr:=160; self.Z0:=VarArrayCreate([0,0],varVariant); self.ffg:=VarArrayCreate([0,0],varVariant); self.MueIm:=VarArrayCreate([0,0],varVariant); self.MueRe:=VarArrayCreate([0,0],varVariant); end; |
Edit:
Ich habe das ganze etwas abgewandelt, um die Fehlerhafte If-Anweisung zu vermeiden:
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: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
| type Mue = class private Precision: Integer; Z0: Variant; ffg: Variant; MueIm: Variant; MueRe: Variant; InCreation: Boolean;
procedure Assign_ffg(f: Variant); procedure Assign_Z(Z: Variant); procedure SetPrecision(X: Integer); procedure Assign_MueIm(Mue: Variant); procedure Assign_MueRe(Mue: Variant);
property Pr: Integer read Precision write SetPrecision;
property CreateMueIm: Variant read MueIm write Assign_MueIm; property CreateMueRe: Variant read MueRe write Assign_MueRe;
public constructor Create();
property Z: Variant read Z0 write Assign_Z; property f_fg: Variant read ffg write Assign_ffg; property Im: Variant read MueIm; property Re: Variant read MueRe; end;
implementation
uses Functions;
procedure TSensor.LO(Z:Integer); begin Lift:=Z; end;
constructor Mue.Create(); begin InCreation:=true; self.Pr:=160; self.Z:=VarArrayCreate([0,0],varVariant); self.f_fg:=VarArrayCreate([0,0],varVariant); self.CreateMueIm:=VarArrayCreate([0,0],varVariant); self.CreateMueRe:=VarArrayCreate([0,0],varVariant); InCreation:=false end;
procedure Mue.SetPrecision(X: Integer); begin Precision:=X; end;
procedure Mue.Assign_ffg(f: Variant); var Index,i: Integer; Z: Extended; begin
if not InCreation then begin Z:=sqrt(f);
for i:=0 to VarArrayHighBound(ffg,1)-1 do begin if (Z > Z0[i]) and (Z < Z0[i+1]) then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision)); end else ffg:=VarArrayCreate([0,0],VarVariant); end;
procedure Mue.Assign_Z(Z: Variant); var Index,i: Integer; f: Extended; begin
if not InCreation then begin f:=Z*Z;
for i:=0 to VarArrayHighBound(Z0,1)-1 do begin if (Z > Z0[i]) and (Z < Z0[i+1]) then Index:=i; end;
VarArrayInsert(Z0,Index,Z); VarArrayInsert(ffg,Index,f); VarArrayInsert(MueIm,Index,MueEffIm(Z,Precision)); VarArrayInsert(MueRe,Index,MueEffRe(Z,Precision));
end else Z0:=VarArrayCreate([0,0],VarVariant); end;
procedure Mue.Assign_MueIm(Mue: Variant); begin MueIm:=VarArrayCreate([0,0],varVariant); end;
procedure Mue.Assign_MueRe(Mue: Variant); begin MueRe:=VarArrayCreate([0,0],varVariant); end; |
Wenn ich einzelne Zeilen aus dem constructor weg-kommentiere, kann ich entsprechend andere Stellen ausführen lassen und jedes mal kommt beim Aufruf von VarArrayCreate die gleiche Fehlermeldung. 
Zuletzt bearbeitet von GR-Thunderstorm am Mo 07.11.11 23:01, insgesamt 1-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 07.11.11 23:00
Vermutung:
Du rufst den Konstruktor fälschlicherweise so auf: Delphi-Quelltext 1: 2: 3: 4:
| var xyz: TMue; begin xyz.Create; | Self ist dann im Konstruktor gar nicht definiert, da es die uninitialisierte Variable xyz ist. Und deshalb knallt es.
Nebenbei:
Es ist Konvention, dass ein Klassenname immer mit T beginnt.
|
|
GR-Thunderstorm 
      
Beiträge: 206
|
Verfasst: Mo 07.11.11 23:04
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Hmm nunja, es wird skuriler:
Ich habe herausgefunden, dass diese Zeile KEINEN Fehler verursacht:
Delphi-Quelltext 1:
| ffg:=VarArrayCreate([0,0],VarVariant); |
Wegen der Konvention: Das werde ich dann mal abändern.
Edit:
Ich habe den Fehler gefunden. >.< Ich wusste erst nicht so genau, was Jaenicke mir mit dem Post sagen wollte. ^^
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var Test: TMue; begin Test.Create(); end;
var Test: TMue; begin Test:=TMue.Create(); end; |
Das erklärt zwar nicht, wieso auf "ffg" zugegriffen werden konnte und auf "Z0" nicht, aber nun klappt alles wunderbar.
Vielen Dank für die Hilfe (und vor allem Geduld!  ) an euch alle!
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 08.11.11 06:51
GR-Thunderstorm hat folgendes geschrieben : | Das erklärt zwar nicht, wieso auf "ffg" zugegriffen werden konnte und auf "Z0" nicht |
Reiner Zufall.
Da du auf die Methode Create des (uninitialisierten) Objekts statt auf den Konstruktor der Klasse zugegriffen hast, hast du dort auf zufällige Stellen im Speicher zugegriffen. Und das knallt eben mal und mal nicht sofort.
|
|
|