Discussion:
Delphi 7, String PChar Problem
(zu alt für eine Antwort)
Wolfgang
2020-04-09 07:45:20 UTC
Permalink
Liebe Delphigemeinde!

Ich sehe scheinbar den Wald vor lauter Bäumen nicht mehr.
Ihr könnt mir da sicher weiterhelfen.

In einem kleinen (~1000 Zeilen) Testprogramm funktioniert das,
in einem großen Projekt stürzt das Programm so heftig, dass
nicht einmal der try except Block greift. Vermute mal dass
die StringList Rueck nicht genug Platz hat um die ~10KB
aus p_Rueck auszunehmen. Wie bekomme ich die Daten auf die
p_Rueck zeigt in die Stringlist kopiert.
Ich danke Euch!

Das ist das relevante Codeschnippsel:

private
...
BufferLen : Integer; // wird mit 40 * 1024 initialisiert
Counter : Integer;
p_Rueck : PChar;

...

Procedure Holen;
var ...
Rueck : TStrings;
...
begin
...
Counter := 0;
// Dient nur dazu wenn der Buffer zu klein ist mit einem
// groesseren Buffer weiter zu machen
repeat
inc(Counter);
p_Rueck := nil;
p_Rueck := StrAlloc((Counter * BufferLen) + 1);
// ShowMessage(IntToStr(StrBufSize(p_Rueck))); // Wert ok
// Antwort aus einer DLL
errno := GetAnswer(HDL,p_Rueck, StrBufSize(p_Rueck) );
if (errno = BUFFERTOSMALL) then
StrDispose(p_Rueck);
Sleep(500);
until (Counter > 3) or (errno <> BUFFERTOSMALL);

if errno = SUCCESS then
begin
Rueck := TStringList.Create;
//StrLCopy(PChar(Rueckm.Text),p_rm,StrLen(p_rm)-1); // strlen ok
//Rueck.Text := String(p_Rueck);
Rueck.Text := StrPas(p_Rueck); // Absturz
StrDispose(p_Rueck);
Rueck.Free;
end;

...
end;

mfg Wolfgang
Wolfgang
2020-04-09 07:52:46 UTC
Permalink
Post by Wolfgang
Liebe Delphigemeinde!
Ich sehe scheinbar den Wald vor lauter Bäumen nicht mehr.
Ihr könnt mir da sicher weiterhelfen.
In einem kleinen (~1000 Zeilen) Testprogramm funktioniert das,
in einem großen Projekt stürzt das Programm so heftig, dass
nicht einmal der try except Block greift. Vermute mal dass
die StringList Rueck nicht genug Platz hat um die ~10KB
aus p_Rueck auszunehmen. Wie bekomme ich die Daten auf die
p_Rueck zeigt in die Stringlist kopiert.
Ich danke Euch!
private
  ...
  BufferLen : Integer;  // wird mit 40 * 1024 initialisiert
  Counter   : Integer;
  p_Rueck   : PChar;
....
Procedure Holen;
  var ...
      Rueck     : TStrings;
      ...
begin
   ...
   Counter := 0;
   // Dient nur dazu wenn der Buffer zu klein ist mit einem
   // groesseren Buffer weiter zu machen
   repeat
         inc(Counter);
         p_Rueck := nil;
         p_Rueck := StrAlloc((Counter * BufferLen) + 1);
         // ShowMessage(IntToStr(StrBufSize(p_Rueck))); // Wert ok
     // Antwort aus einer DLL
         errno := GetAnswer(HDL,p_Rueck, StrBufSize(p_Rueck) );
         if (errno = BUFFERTOSMALL) then
            StrDispose(p_Rueck);
         Sleep(500);
   until (Counter > 3) or (errno <> BUFFERTOSMALL);
   if errno = SUCCESS then
      begin
      Rueck := TStringList.Create;
      //StrLCopy(PChar(Rueckm.Text),p_rm,StrLen(p_rm)-1); // strlen ok
      //Rueck.Text := String(p_Rueck);
      Rueck.Text := StrPas(p_Rueck); // Absturz
      StrDispose(p_Rueck);
      Rueck.Free;
      end;
   ...
end;
mfg Wolfgang
Sorry habe vergessen zu erwähnen dass es sich um D7 auf
XP und Windows 7 x86 mit allen Updates handelt.
Christian Schmitt
2020-04-10 16:04:45 UTC
Permalink
Post by Wolfgang
In einem kleinen (~1000 Zeilen) Testprogramm funktioniert das,
in einem großen Projekt stürzt das Programm so heftig, dass
nicht einmal der try except Block greift.
Bist du mit dem Debugger mal in die Zuweisungsfunktion von TStringList.Text hineingesprungen, um mal zu sehen bei welcher Anweisung genau der Crash passiert?
Post by Wolfgang
Vermute mal dass
die StringList Rueck nicht genug Platz hat um die ~10KB
aus p_Rueck auszunehmen. Wie bekomme ich die Daten auf die
p_Rueck zeigt in die Stringlist kopiert.
Ich habe nur Delphi XE, hier ist die TStringList intern als Array aufgebaut, daher - vorausgesetzt dein Arbeitsspeicher reicht :-) - sollte das kein Problem sein.

Mir kommt noch fix folgender Gedanke: D7 ist doch noch nicht Unicode basiert, bist du sicher, dass die DLL einen Zeiger auf einen PAnsiChar zurückliefert? Nicht dass du hier Unicode zurück bekommst, dann könnte die Größenberechnung für deinen PChar falsch sein...

Zweiter Ansatz: StrBufSize gibt die Zeichenanzahl inklusive des Nullterminators zurück. Sicher dass es hier kein Problem gibt? Nicht dass die DLL den Nullterminator überschreibt (geht das überhaupt?) und die .Text-Funktion dann quasi das Ende nicht findet...?

Was enthält dein PChar denn, hast du da mal reingeschaut?

Alles gerade nur so kurze Gedanken...

Happy Easter!

Gruß
Wolfgang
2020-04-13 08:08:20 UTC
Permalink
Danke für deine Antwort!
Post by Christian Schmitt
Post by Wolfgang
private
...
BufferLen : Integer; // wird mit 40 * 1024 initialisiert
Counter : Integer;
p_Rueck : PChar;
....
function GetAnswer (h:hwnd;pRD:Pchar;nMaxRDLen:Integer):Integer;
stdcall; external 'ext.dll';
Post by Christian Schmitt
Post by Wolfgang
Procedure Holen;
var ...
Rueck : TStrings;
...
begin
...
Counter := 0;
// Dient nur dazu wenn der Buffer zu klein ist mit einem
// groesseren Buffer weiter zu machen
repeat
inc(Counter);
p_Rueck := nil;
p_Rueck := StrAlloc((Counter * BufferLen) + 1);
// ShowMessage(IntToStr(StrBufSize(p_Rueck))); // Wert ok
// Antwort aus einer DLL
errno := GetAnswer(HDL,p_Rueck, StrBufSize(p_Rueck) );
if (errno = BUFFERTOSMALL) then
StrDispose(p_Rueck);
Sleep(500);
until (Counter > 3) or (errno <> BUFFERTOSMALL);
if errno = SUCCESS then
begin
Rueck := TStringList.Create;
//StrLCopy(PChar(Rueckm.Text),p_rm,StrLen(p_rm)-1); // strlen ok
//Rueck.Text := String(p_Rueck);
Rueck.Text := StrPas(p_Rueck); // Absturz
StrDispose(p_Rueck);
Rueck.Free;
end;
...
end;
In einem kleinen (~1000 Zeilen) Testprogramm funktioniert das,
in einem großen Projekt stürzt das Programm so heftig, dass
nicht einmal der try except Block greift.
Bist du mit dem Debugger mal in die Zuweisungsfunktion von TStringList.Text hineingesprungen, um mal zu sehen bei welcher Anweisung genau der Crash passiert?
Post by Wolfgang
Vermute mal dass
die StringList Rueck nicht genug Platz hat um die ~10KB
aus p_Rueck auszunehmen. Wie bekomme ich die Daten auf die
p_Rueck zeigt in die Stringlist kopiert.
Ich habe nur Delphi XE, hier ist die TStringList intern als Array aufgebaut, daher - vorausgesetzt dein Arbeitsspeicher reicht :-) - sollte das kein Problem sein.
Sollte vom Speicher kein Problem sein. Maximum war mal 70KB. Das ist
aber genau so viel, dass ich mit diesem funktionierenden Konstrukt mit
array of char nicht mehr arbeiten kann.

function GetAnswer(h:hwnd;var RD:Array of
Char;nMaxRDLen:Integer):Integer; stdcall; external 'ext.dll';

Rueck : Array[0..60000] of Char; // Kann halt dann nicht 70KB

errno := GetAnswer(HDL,Rueck,length(Rueck));

Ist StrPas zum kopieren von einem PChar überhaupt die richtige Funktion?
Post by Christian Schmitt
Mir kommt noch fix folgender Gedanke: D7 ist doch noch nicht Unicode basiert, bist du sicher, dass die DLL einen Zeiger auf einen PAnsiChar zurückliefert? Nicht dass du hier Unicode zurück bekommst, dann könnte die Größenberechnung für deinen PChar falsch sein...
Ist sicher kein Unicode String.
DLL C : int GetAnswer(HANDLE h, LPSTR pRD, int nMaxRDLen);
Post by Christian Schmitt
Zweiter Ansatz: StrBufSize gibt die Zeichenanzahl inklusive des Nullterminators zurück. Sicher dass es hier kein Problem gibt? Nicht dass die DLL den Nullterminator überschreibt (geht das überhaupt?) und die .Text-Funktion dann quasi das Ende nicht findet...?
Was enthält dein PChar denn, hast du da mal reingeschaut?
Die DLL sollte eigentlich einen Nullterminierten String zurückliefern.
Sieht vom Debugger aus soweit gut aus aber werde da nochmal genauer
wegen des #0 reinschauen.
Post by Christian Schmitt
Alles gerade nur so kurze Gedanken...
Happy Easter!
Gruß
lg Wolfgang
Christian Schmitt
2020-04-20 08:09:35 UTC
Permalink
Post by Wolfgang
Sollte vom Speicher kein Problem sein. Maximum war mal 70KB. Das ist
aber genau so viel, dass ich mit diesem funktionierenden Konstrukt mit
array of char nicht mehr arbeiten kann.
function GetAnswer(h:hwnd;var RD:Array of
Char;nMaxRDLen:Integer):Integer; stdcall; external 'ext.dll';
Rueck : Array[0..60000] of Char; // Kann halt dann nicht 70KB
errno := GetAnswer(HDL,Rueck,length(Rueck));
Stehe ich hier auf dem Schlauch oder warum kannst du die 60000 nicht in 71680 (70kB) ändern?
Post by Wolfgang
Ist StrPas zum kopieren von einem PChar überhaupt die richtige Funktion?
Ja, wobei ich die explizit eigentlich nie genutzt habe. Ich habe immer eine direkte Zuweisung gemacht, in deinem Fall wäre das dann

Rueck.Text := p_Rueck;

Hatte damit noch nie Probleme.
Post by Wolfgang
Post by Christian Schmitt
Bist du mit dem Debugger mal in die Zuweisungsfunktion von TStringList.Text hineingesprungen, um mal zu sehen bei welcher Anweisung genau der Crash passiert?
Haste mal geschaut?

Gruß
Wolfgang
2020-04-20 11:52:58 UTC
Permalink
Post by Christian Schmitt
Post by Wolfgang
Sollte vom Speicher kein Problem sein. Maximum war mal 70KB. Das ist
aber genau so viel, dass ich mit diesem funktionierenden Konstrukt mit
array of char nicht mehr arbeiten kann.
function GetAnswer(h:hwnd;var RD:Array of
Char;nMaxRDLen:Integer):Integer; stdcall; external 'ext.dll';
Rueck : Array[0..60000] of Char; // Kann halt dann nicht 70KB
errno := GetAnswer(HDL,Rueck,length(Rueck));
Stehe ich hier auf dem Schlauch oder warum kannst du die 60000 nicht in 71680 (70kB) ändern?
Post by Wolfgang
Ist StrPas zum kopieren von einem PChar überhaupt die richtige Funktion?
Ja, wobei ich die explizit eigentlich nie genutzt habe. Ich habe immer eine direkte Zuweisung gemacht, in deinem Fall wäre das dann
Rueck.Text := p_Rueck;
Hatte damit noch nie Probleme.
Post by Wolfgang
Post by Christian Schmitt
Bist du mit dem Debugger mal in die Zuweisungsfunktion von TStringList.Text hineingesprungen, um mal zu sehen bei welcher Anweisung genau der Crash passiert?
Haste mal geschaut?
Gruß
Wenn ich > 65535 (Int) komme dann kommt in einer Funktion einer Form wo
diese Variable verwendet wird: [Fehler] : Zuviele lokale Konstanten.
Verwenden Sie kürzere Prozeduren.

lg Wolfgang
Christian Schmitt
2020-04-21 07:20:59 UTC
Permalink
Post by Wolfgang
Wenn ich > 65535 (Int) komme dann kommt in einer Funktion einer Form wo
diese Variable verwendet wird: [Fehler] : Zuviele lokale Konstanten.
Verwenden Sie kürzere Prozeduren.
Ist bei D7 Int <> LongInt? Ansonsten geht ein Integer eigentlich bis 2^32/2, daher wundert mich das gerade.
Und mit einer Stringlist würde es funktionieren? Imho ist das auch nix anderes wie ein array.

Haste mal versucht das StrPas wegzulassen, also den Compiler selbsttätig die Umwandlung vornehmen zu lassen?

Rueck.Text := p_Rueck;

Gruß
Wolfgang
2020-04-21 12:40:12 UTC
Permalink
Post by Christian Schmitt
Post by Wolfgang
Wenn ich > 65535 (Int) komme dann kommt in einer Funktion einer Form wo
diese Variable verwendet wird: [Fehler] : Zuviele lokale Konstanten.
Verwenden Sie kürzere Prozeduren.
Ist bei D7 Int <> LongInt? Ansonsten geht ein Integer eigentlich bis 2^32/2, daher wundert mich das gerade.
Und mit einer Stringlist würde es funktionieren? Imho ist das auch nix anderes wie ein array.
Haste mal versucht das StrPas wegzulassen, also den Compiler selbsttätig die Umwandlung vornehmen zu lassen?
Rueck.Text := p_Rueck;
Gruß
Hi!

sysutils:

function StrPas(const Str: PChar): string;
begin
Result := Str;
end;

StrPas() macht genau das.

lg Wolfgang
Alfred Gemsa
2020-04-21 16:14:39 UTC
Permalink
Post by Wolfgang
In einem kleinen (~1000 Zeilen) Testprogramm funktioniert das,
in einem großen Projekt stürzt das Programm so heftig, dass
nicht einmal der try except Block greift. Vermute mal dass
die StringList Rueck nicht genug Platz hat um die ~10KB
aus p_Rueck auszunehmen. Wie bekomme ich die Daten auf die
p_Rueck zeigt in die Stringlist kopiert.
Ich danke Euch!
Ich habe mal was gebastelt:

Auf dem Formular ist eint Editfeld, wo die Länge eingetragen wird, ein
Memo, was dann die erzeugte Stringliste anzeigt und ein Button zum Start:

type
TForm1 = class(TForm)
Edit1: TEdit;
Memo1: TMemo;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
sl: TStringList;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
sl := TStringList.create;
end;

procedure TForm1.Button2Click(Sender: TObject);
var i, len: integer;
pc: pChar;
s, s1: string;
begin
len := strtoint(Edit1.Text);
//
// langen String zusammenbasteln
//
for i:=1 to len do
s := s + inttostr(i mod 10);
//
// Terminierende Null
//
s := s + #0;
//
// pChar erzeugen
//
pc := nil;
pc := StrAlloc(len + 1);
//
// String auf pChar übertragen, mit Terminator
//
move(s[1], pc^, len + 1);
//
// pChar auf anderen String kopieren (StrPas)
//
s1 := strpas(pc);
//
// Anderen String in Stringliste eintragen und anzeigen
//
sl.Clear;
sl.Text := s1;
Memo1.Lines.Assign(sl);
end;

end.

Der Unterschied zu deinem Code ist, dass ich mit StrPas zuerst einen
normalen String fülle (s1) und den dann in die Stringliste schreibe.

Ich habe es bis 100.000 getestet, strpas geht damit.

HTH, Alfred;
Alfred Gemsa
2020-04-21 16:15:21 UTC
Permalink
Ich vergaß: Windows 10, Delphi 7.
Christian Schmitt
2020-04-22 05:55:30 UTC
Permalink
Post by Alfred Gemsa
Der Unterschied zu deinem Code ist, dass ich mit StrPas zuerst einen
normalen String fülle (s1) und den dann in die Stringliste schreibe.
Und wenn du das nicht machst kracht es? Kannst du den Fehler von Wolfgang reproduzieren?

Gruß
Alfred Gemsa
2020-04-22 09:04:02 UTC
Permalink
Post by Christian Schmitt
Post by Alfred Gemsa
Der Unterschied zu deinem Code ist, dass ich mit StrPas zuerst einen
normalen String fülle (s1) und den dann in die Stringliste schreibe.
Und wenn du das nicht machst kracht es? Kannst du den Fehler von Wolfgang reproduzieren?
//
// pChar erzeugen
//
pc := StrAlloc(len + 1);
move(s[1], pc^, len + 1);
//
// pChar-Inhalt direkt in Stringliste eintragen und anzeigen
//
sl.Text := strpas(pc);
Memo1.Lines.Assign(sl);
//
//
StrDispose(pc);

Geht auch.

Wolfgang nimmt ein TStrings:

var ...
Rueck : TStrings;
...

Ich hingegen trage das Zeug in eine Stringliste ein:

private
sl: TStringList;

Nehme ich TStrings, krachts auch bei mir. Dabei wird ein "AbstractError"
Post by Christian Schmitt
von TStrings wird nur abgeleitet. Die Funktion Count ist dort nur als
abstract deklariert und muss in den abgeleiteten Klassen angegeben
werden.
TStringList ist von TStrings abgeleitet und stellt alle Methoden zur
Verfügung. Nimm also nicht TStrings sondern TStringList (TStrings
kann > als Typ bei den Übergabeparametern verwendet werden).

Die Delphi-Hilfe sagt:

Beschreibung
Post by Christian Schmitt
Von TStrings abgeleitete Objekte ermöglichen die Speicherung und
Bearbeitung von String-Listen. TStrings enthalten abstrakte bzw. rein
virtuelle (C++ Terminologie) Methoden und sollten nicht direkt
instantiiert werden.
Nachkommen von TStrings können entweder unterschiedliche
Zeichenketten > (wie z.B. die einzelnen Zeilen eines Listenfeldes) oder
eine einzige
Post by Christian Schmitt
lange Texteinheit repräsentieren, deren Elemente dann separat
bearbeitet werden können. Die Eigenschaften und Methoden von TStrings
bieten zahlreiche Werkzeuge zur String-Listenbearbeitung an.
Alfred
Wolfgang
2020-04-22 13:36:58 UTC
Permalink
Post by Christian Schmitt
Post by Alfred Gemsa
Der Unterschied zu deinem Code ist, dass ich mit StrPas zuerst einen
normalen String fülle (s1) und den dann in die Stringliste schreibe.
Und wenn du das nicht machst kracht es? Kannst du den Fehler von Wolfgang reproduzieren?
  //
  // pChar erzeugen
  //
  pc := StrAlloc(len + 1);
  move(s[1], pc^, len + 1);
  //
  // pChar-Inhalt direkt in Stringliste eintragen und anzeigen
  //
  sl.Text := strpas(pc);
  Memo1.Lines.Assign(sl);
  //
  //
  StrDispose(pc);
Geht auch.
  var ...
      Rueck     : TStrings;
      ...
  private
    sl: TStringList;
Nehme ich TStrings, krachts auch bei mir. Dabei wird ein "AbstractError"
Post by Christian Schmitt
von TStrings wird nur abgeleitet. Die Funktion Count ist dort nur als
abstract deklariert und muss in den abgeleiteten Klassen angegeben
werden.
TStringList ist von TStrings abgeleitet und stellt alle Methoden zur
Verfügung. Nimm also nicht TStrings sondern TStringList (TStrings
kann > als Typ bei den Übergabeparametern verwendet werden).
Beschreibung
Post by Christian Schmitt
Von TStrings abgeleitete Objekte ermöglichen die Speicherung und
Bearbeitung von String-Listen. TStrings enthalten abstrakte bzw. rein
virtuelle (C++ Terminologie) Methoden und sollten nicht direkt
instantiiert werden.
Nachkommen von TStrings können entweder unterschiedliche
Zeichenketten > (wie z.B. die einzelnen Zeilen eines Listenfeldes) oder
eine einzige
Post by Christian Schmitt
lange Texteinheit repräsentieren, deren Elemente dann separat
bearbeitet werden können. Die Eigenschaften und Methoden von TStrings
bieten zahlreiche Werkzeuge zur String-Listenbearbeitung an.
Alfred
Hallo!

Super danke das war die Lösung.
TStrings war auch bei mir der Schuldige. Nehme ich TStringList klappt
das ohne Absturz auch ohne den Umweg über die Zuweisung an einen String.

So sieht es jetzt aus:

private
...
BufferLen : Integer; // wird mit 40 * 1024 initialisiert
Counter : Integer;
p_Rueck : PChar;

....
function GetAnswer(h:hwnd;RD:PChar;nMaxRDLen:Integer):Integer; stdcall;
external 'ext.dll';
...
Procedure Holen;
var ...
Rueck : TStringList;
...
begin
...
Counter := 0;
// Dient nur dazu wenn der Buffer zu klein ist mit einem
// groesseren Buffer weiter zu machen
repeat
inc(Counter);
p_Rueck := nil;
p_Rueck := StrAlloc((Counter * BufferLen) + 1);
errno := GetAnswer(HDL,p_Rueck, Counter * BufferLen);
if (errno = BUFFERTOSMALL) then
StrDispose(p_Rueck);
Sleep(500);
until (Counter > 3) or (errno <> BUFFERTOSMALL);

if errno = SUCCESS then
begin
Rueck := TStringList.Create;
Rueck.Text := StrPas(p_Rueck);
StrDispose(p_Rueck);
Rueck.Free;
end;
...
end;

Danke für Eure Hilfe!

lg Wolfgang
Christian Schmitt
2020-04-23 10:08:02 UTC
Permalink
Post by Wolfgang
var ...
Rueck : TStrings;
...
Ohwei, das ist mir gar nicht aufgefallen. Hier ist ja auch ein Typ-Missmatch: TStrings:=TStringlist.create; Ich habe gerade nachgeschaut, in meinem Testprogramm hab ich instinktiv Rueck:TStringlist genommen. Hab aber jetzt gerade mal mit Fehler ausprobiert, also Delphi XE2 und Win 8.1 machen hier keinen Crash.

@Alfred: Das ärgert mich jetzt, dass ich den Fehler nicht vor dir gefunden habe :-))

Gruß
Alfred Gemsa
2020-04-23 10:30:18 UTC
Permalink
Post by Christian Schmitt
@Alfred: Das ärgert mich jetzt, dass ich den Fehler nicht vor dir gefunden habe :-))
Tja, man muss och jönne könne. ;-)

Ich habe mehr als dreißig Jahre beruflich mit Delphi rumgemacht und bin
inzwischen im Ruhestand.

Jetzt weiß ich endlich, was abstrakte Methoden sind, man lernt nie aus.

Alfred.
Christian Schmitt
2020-04-23 13:29:38 UTC
Permalink
Post by Alfred Gemsa
Tja, man muss och jönne könne. ;-)
Ik jönns dir ja, wa? :-)
Alfred Gemsa
2020-04-23 13:40:32 UTC
Permalink
Post by Christian Schmitt
Post by Alfred Gemsa
Tja, man muss och jönne könne. ;-)
Ik jönns dir ja, wa? :-)
Ah jetzt ja:

Gruß aus der Kölner Gegend an die Havel!
Wolfgang
2020-04-23 12:14:51 UTC
Permalink
Post by Christian Schmitt
Post by Wolfgang
var ...
Rueck : TStrings;
...
Ohwei, das ist mir gar nicht aufgefallen. Hier ist ja auch ein Typ-Missmatch: TStrings:=TStringlist.create; Ich habe gerade nachgeschaut, in meinem Testprogramm hab ich instinktiv Rueck:TStringlist genommen. Hab aber jetzt gerade mal mit Fehler ausprobiert, also Delphi XE2 und Win 8.1 machen hier keinen Crash.
@Alfred: Das ärgert mich jetzt, dass ich den Fehler nicht vor dir gefunden habe :-))
Gruß
Mach dir keine Kopf. Mir ist es auch Jahre nicht aufgefallen und das war
des öfteren im Einsatz.;-( Der Compiler liefert nicht eimal eine
Warnung. Ich bin auf jeden Fall sehr froh dass das Problem jetzt behoben
ist. *g* Danke!

lg Wolfgang
Alfred Gemsa
2020-04-23 13:28:01 UTC
Permalink
Post by Wolfgang
Mach dir keine Kopf. Mir ist es auch Jahre nicht aufgefallen und das war
des öfteren im Einsatz.;-( Der Compiler liefert nicht eimal eine
Warnung. Ich bin auf jeden Fall sehr froh dass das Problem jetzt behoben
ist. *g* Danke!
Das sehe ich allerdings, wenn ich TStrings nehme_

[Warnung] Unit1.pas(29): Instanz von 'TStrings' mit der abstrakten
Methode 'TStrings.Clear' wird angelegt
[Warnung] Unit1.pas(29): Instanz von 'TStrings' mit der abstrakten
Methode 'TStrings.Delete' wird angelegt
[Warnung] Unit1.pas(29): Instanz von 'TStrings' mit der abstrakten
Methode 'TStrings.Insert' wird angelegt

Alfred.
Jens Köhler
2020-04-29 15:23:52 UTC
Permalink
Post by Alfred Gemsa
Das sehe ich allerdings, wenn ich TStrings nehme_
[Warnung] Unit1.pas(29): Instanz von 'TStrings' mit der abstrakten
Methode 'TStrings.Insert' wird angelegt
Alfred.
Hallo,

wo ist da eigentlich das Problem?

es ist zwar
Rueck : TStrings deklariert aber mit
Rueck := TStringList.Create; erzeugt.

Da mache ich eignetlich immer so und bin der Meinung das auch in der
Doku und in Beispielen gesehen zu haben das die Basisklasse deklariert
und die Spazialität erzeugt wird.
Auch als Parameter ist TStrings öfters deklariert.

Jens

Loading...