Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi CE 12: constructor und Free vertragen sich nicht mit den destructor ? (https://www.delphipraxis.net/215618-ce-12-constructor-und-free-vertragen-sich-nicht-mit-den-destructor.html)

paule32.jk 6. Aug 2024 17:27

CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Hallo,
ich habe folgenden Code:

Delphi-Quellcode:
{$APPTYPE CONSOLE}
program fpcqt;

uses Windows, SysUtils;

var
  DLLHandle: HMODULE;

type
  TMyFunction = procedure(s: PChar; v: DWORD); cdecl;
  TCTOR_QChar = function(s: PChar): uint64; cdecl;
  TDTOR_QChar = procedure(v: uint64); cdecl;
var
  MyFunction: TMyFunction;

  CTOR_QChar: TCTOR_QChar;
  DTOR_QChar: TDTOR_QChar;

type
  QChar = class
  private
    ptr_cc: uint64;
  public
    constructor Create;
    destructor Destroy;
  end;

var
  myQChar: QChar;

constructor QChar.Create;
begin
  ptr_cc := CTOR_QChar(PChar('ctor_QChar'));
  WriteLn(Format('ctor1 ptr: %x',[ptr_cc]));
end;

destructor QChar.Destroy;
begin
  WriteLn('ende');
  WriteLn(Format('dtor1 ptr: %x',[ptr_cc]));
  DTOR_QChar(ptr_cc);
  WriteLn(Format('dtor2 ptr: %x',[ptr_cc]));
end;

function check_dllfun(name: String): Pointer;
var p: Pointer;
begin
  p := GetProcAddress(DLLHandle, PChar(name));
  if p = nil then
  begin
    MessageBox(0,
    PChar('Error: Function not found in DLL.' + #13 + name),
    PChar('Error'),
    MB_OK);
    ExitProcess(1);
  end else
  begin
    result := p;
  end;
end;

begin
  DLLHandle := LoadLibrary('fpc-qt.dll');
  if DLLHandle = 0 then
  begin
    MessageBox(0,'Error: DLL could not be loaded.','Error',0);
    ExitProcess(1);
  end;
  try
    @MyFunction := GetProcAddress(DLLHandle, 'addsymbol');

    @CTOR_QChar := check_dllfun('ctor_QChar');
    @DTOR_QChar := check_dllfun('dtor_QChar');

    MyFunction(PChar('jukel'), 2);
    WriteLn('ooo');

    myQChar := QChar.Create;
    myQChar.Free;                // hier
    WriteLn('oooo');
  finally
      FreeLibrary(DLLHandle);
      ExitProcess(0);
  end;
end.
- wenn ich den constructor QChar.Create aufrufe, dann wird der Delphi CTOR aufgerufen.
- wenn ich aber den destructor durch die Anweisung myQChar.Free; aufrufen möchte, wird der DTOR nicht aufgerufen.
- wenn ich aber den destructor direkt aufrufe, mittels: myQChar.Destroy; wird der DTOR von Delphi aufgerufen.

Hat sich da was geändert, an der Programmierreihenfolge ?
Also, das Free nicht mehr für das "aufräumen" verwendet werden kann ?
wo liegt mein Fehler ?

himitsu 6. Aug 2024 18:03

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Delphi-Quellcode:
override;
am Destructor vergessen ... du wolltest nicht, dass der aufgerufen wird, also wurde er nicht. :stupid:
und
Delphi-Quellcode:
inherited;
kennst du?

Gibt FreePascal denn keine Meldungen dazu raus?
Delphi macht das. :angle2:
Zitat:

[dcc32 Warnung] Unit1.pas(31): W1010 Methode 'Destroy' verbirgt virtuelle Methode vom Basistyp 'TObject'


PS: statt #13 besser #10 oder #13#10 oder sLineBreak (oder wie diese Konstante im Lazarus/FPC heißen mag)
ein einzelnes #13 nutzen eigentlich nur der urururalte MAC und im Windows das TRichEdit (z.B. RichEdit50).

paule32.jk 6. Aug 2024 18:11

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
ahja, okay.
Du hast recht !
wird als "verbirgt" angezeigt.
Aber der Delphi CE 12 Compiler meldet Erfolg.

kann man irgendwie die Schriftgröße von Delphi Text einschließlich MenuSchrift nicht größer einstellen ?
Ich habe hier einen 1900x1200 Bildschirm, und ich möchte ungern die Schrift-Einstellungen über die Windows-Einstellungen global ändern.

Edit:
Delphi-Quellcode:
function check_dllfun(name: String): Pointer;
var p: Pointer;
begin
  result := nil;
  p := GetProcAddress(DLLHandle, PChar(name));
  if p = nil then
  begin
    MessageBox(0,
    PChar('Error: Function not found in DLL.' + #13 + name),
    PChar('Error'),
    MB_OK);
    ExitProcess(1);
  end;
end;
jetzt funktioniert alles wie erwünscht.

himitsu 6. Aug 2024 18:19

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Erfolg ja. Ist ja nur eine Warning und kein Error oder Fatal.
Eventuell nochmal ein neues "Erzeugen" durchführen? (Shift+F9)


Menüschrift weiß ich jetzt nicht, aber die Editorschrift versteckt sich in den IDE-Optionen und sogar schon im Setup auswählbar ... dort wo das Design (Hell, Dark und Nebellig) gewählt wird.

siehe IDE-Insight
[F6] bzw. im Suchfeld der Optionen
gibt Mehreres zum Thema "schrift"


Beim Start der IDE kann man auch einen Parameter bezüglich HighDPI angeben. Mal im Forum danach suchen?
Im Startmenü nachsehen, dort findet sich ein "Delphi 12 (DPI Unaware)",

jaenicke 6. Aug 2024 21:28

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Ich habe hier gerade kein Delphi, aber die Schriftgröße kann man per Strg + + oder Strg + - verändern und per Strg + 0 auf Standard setzen. In den Optionen findest du die Schriftart unter Editor-Optionen --> Anzeige oder so.

himitsu 6. Aug 2024 23:03

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
im D12 unten die TrackBar (beinah glatt vergessen)

und ja, Strg mit + und -
kein Strg+0 und leider auch kein Strg+Scrollrad :cry:

Optionen > Editor > Anzeige > Editorschrift

außerdem
Optionen > Editor > Sprache > Insight-Optionen > Editorschriftart verwenden
("Insight" wie CodeCompletion ... nicht wie CodeInsight :freak:)


und das Andere war
Optionen > Benutzeroberfläche > IDE-Schriftart
(aber erst nach Neustart)

CodeInsight/HelpInsight, WellcomePage, FormDesigner, Hilfe ... k.A.

paule32.jk 7. Aug 2024 07:50

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Hallo,
in der Dokumentation zu Delphi steht, das char einen WideChar entspricht.
Aber: kann man denn nicht mehr Datentypen, die ein Byte groß sind deklarieren ?
Was ist denn, wenn man Seriale Anwendungen schreiben möchte, die einen älteren Touch haben, und immer nur zwei Bytes in einen Vorgang übertragen (was dann sicherlich bedeuten würde, das die zu übertragende Datenmenge zeitlich um den Faktor 2 sinkt ?).

Delphi-Quellcode:
type
  QChar = class
  private
    ptr_cc: uint64;
  public
    constructor Create; overload;
    constructor Create(c: Char); overload; // hier
    constructor Create(c: Byte); overload;
    constructor Create(c: AnsiChar); overload; // und da: entspricht Char
    constructor Create(c: WideChar); overload; // und nu ? - kein Char, kein AnsiChar, nur Wide ?
    constructor Create(c: DWORD); overload;
    constructor Create(c: Word); overload;
    destructor Destroy; override;
    function isDigit: Boolean;
  end;

uligerhardt 7. Aug 2024 08:39

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Zitat:

Zitat von paule32.jk (Beitrag 1539614)
Hallo,
in der Dokumentation zu Delphi steht, das char einen WideChar entspricht.
Aber: kann man denn nicht mehr Datentypen, die ein Byte groß sind deklarieren ?
Was ist denn, wenn man Seriale Anwendungen schreiben möchte, die einen älteren Touch haben, und immer nur zwei Bytes in einen Vorgang übertragen (was dann sicherlich bedeuten würde, das die zu übertragende Datenmenge zeitlich um den Faktor 2 sinkt ?).

Delphi-Quellcode:
type
  QChar = class
  private
    ptr_cc: uint64;
  public
    constructor Create; overload;
    constructor Create(c: Char); overload; // hier
    constructor Create(c: Byte); overload;
    constructor Create(c: AnsiChar); overload; // und da: entspricht Char
    constructor Create(c: WideChar); overload; // und nu ? - kein Char, kein AnsiChar, nur Wide ?
    constructor Create(c: DWORD); overload;
    constructor Create(c: Word); overload;
    destructor Destroy; override;
    function isDigit: Boolean;
  end;

AnsiChar ist der 1-Byte-Typ, das passt schon. Aber Overloads für Char, AnsiChar und WideChar erscheint mir zuviel. Ich würde den für Char streichen und explizit für AnsiChar und WideChar überladen (denke ich ;-)).

jaenicke 7. Aug 2024 10:04

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Zitat:

Zitat von paule32.jk (Beitrag 1539614)
Was ist denn, wenn man Seriale Anwendungen schreiben möchte

Dafür gibt es RawByteString, womit keine Zeichensatzumwandlungen usw. passieren, was dafür auch sehr wichtig ist.

paule32.jk 7. Aug 2024 11:06

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
weil ich hier schon mit so vielen Datentypen jongliere...
Ich habe gerade gesehen, das auch Delphi generics/templates unterstützt...
Wie kann man denn das mit Templates lösen, weil ich für jeden CTOR den Char-Typ speichern möchte...

Ohne Templates würde bedeuten, das ich mehrere Variablen/Properties halten müsste... ?
Mit Templates könnte ich doch eine interne Klassen-Variable deklarieren, die dann die Unterscheidung macht... ?

Mit dieser Thematik bin ich aber ehrlich gesagt noch sehr grün hinter den Ohren...
Und für sachdienliche Hinweise wie immer dankbar.

himitsu 7. Aug 2024 14:36

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Zitat:

Zitat von jaenicke (Beitrag 1539616)
Dafür gibt es RawByteString,

Oder man nimmt z.B. TBytes.

Zitat:

Zitat von paule32.jk (Beitrag 1539614)
Delphi-Quellcode:
    constructor Create(c: Char); overload; // hier
    constructor Create(c: AnsiChar); overload; // und da: entspricht Char
    constructor Create(c: WideChar); overload; // und nu ? - kein Char, kein AnsiChar, nur Wide ?

Bis Delphi 2006/2007 Char=AnsiChat und seit Delphi 2009 Char=WideChar, da Delphi standardmäßig auf Unicode umgestellt wurde.
Ebenso ist nun MessageBox ein alias für MessageBoxW und früher war es ein MessageBoxA.

Also ich würde einfach das Char weglassen ... oder das WideChar, aber ohne Char wäre es eindeutiger.



Delphi 12 prüft einige Typen anders/genauer,
darunter vor allem nun Alias, welche eigentlich "identisch" sind, aber nun doch nicht mehr.

Drum wird z.B. bei SendMessage nun auch LPARAM und WPARAM als Typ angezeigt, welche früher als LongInt im CodeInsight standen.



PChar ist seit 2009 ein PWideChar,
so wie auch Char ein WideChar
und String ein UnicodeString.

Vor 2009 waren sie Alias zu den ANSI-Typen.

WideString ist der BSTR vom OLE32, siehe MSDN-Library durchsuchenSysAllocString


Früher gingen Overloads mit "gleichen" Typen garnicht, also Char und WideChar sind ja "eigentlich" gleich, bzw. das Eine ist nur ein Alias des Anderen und keine eigenständigen Typen,
aber solche Typen lassen sich JETZT dennoch unterscheiden (Fluch und Segen zugleich).



Bei Lazarus/FreePascal muß man aufpassen, denn die sind bei ANSI geblieben, bzw. nutzen an vielen Stellen nun UTF8String, welches einen AnsiString entspricht.



Es gibt ShortString (bis 255 Zeichen) bzw. String[x] (ein ShortString mit definierter Maximallänge)
die LongString (AnsiString und UnicodeString)
den WideString (der OLE32-API-Wrapper)
und irgendeinen UCS4-String (4 Byte pro Char, aber da ist nichts richtig implementiert)

Und mit AnsiString(x) ein paar Ableitungen des AnsiString, mit definierter Codepage.
der normale AnsiString mit CP_ACP (in einer ConsolenApp könnte es auch CP_OEM sein, jenachdem wie die WinAPIs konfiguriert sind)
UTF8String mit CP_UTF8
RawByteString mit CodePage $FFFF, wobei hier die Chars von #0 bis #255 einfach 1:1 konvertiert/kopiert werden.

die WideString und UnicodeString sind normal UTF-16 (PS, man kann auch einen AnsiString mit der UTF-16-Codepage definieren, in BigEndian oder LittleEndian)

Und beim Zuweisen der verschiedenen Stringtypen untereinander, konvertiert Delphi dann automatisch, entsprechend ihrer "aktuellen" CodePages.

paule32.jk 7. Aug 2024 15:12

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
wäre denn der VARIANT eine bessere Lösung ?
also, das man noch die ctor's hat, aber für den Typ dann einen Variant ?

weil, ich nutze im Moment verschiedene Typen in C++, die nach Delphi, und von Delphi nach C++ wandern.
C++ kennt ja uint8_t, uint16_t, uint32_t, und uint64_t.

komischerweise entspricht dann ein uint64_t einen void*
und uint64_t in Delphi, der gleiche Typ UInt64.

Jetzt wirds lustig:
diesen UInt64 kann ich auch in einen String konvertieren, den man dann wieder durch
reinterpret_cast<QChar*>(addr) zu einen Pointer der erstellten Klasse QChar konvertieren kann.

Also das ist zwar möglich.
Aber in meinen Augen recht umständlich, weil man sich sehr genau an ein Protokoll, das man vorher ausarbeiten sollte, halten muss, damit die Konvertierung nicht in AMV endet.
Aber wie soll man das auch machen, wenn man unterschiedliche Systeme hat.

Ich weiß, jetzt kommt wieder ein Artikel von Interfaces und .NET
Aber: der GNU C/C++ Compiler ist da ein wenig Eigen, und man muss sich was anderes einfallen lassen (für mich zumindest).

Wie das gerade jetzt funktioniert, ist gut (Delphi -> GNU C/C++ > Delphi).
Allerdings müsste ich noch weiter testen mit (FPC -> GNU C/C++ -> FPC).

himitsu 7. Aug 2024 15:35

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
Kommt drauf an.

Variant kennt "direkt" kein RawByteString, aber es kennt Byte-Arrays, allerdings handhabt man das schon bissl umständlicher.
AnsiString und UnicodeString kennt er nur innerhalb des Delphi
und sonst kennt es halt nur noch den BSTR (WideString) und PAnsiChar, sowie PWideChar.

Ja, man kann Variant/OleVariant für Binärdaten nutzen, aber es gibt auch Einfacheres.

C++ kennt Variant OleVariant, aber es kennt auch den BSTR
und ansonsten halt z.B. PAnsiChar oder "statische" ByteArray usw.

Wenn C-seitig nur gelesen wird, kann man auch AnsiString und UnicodeString als Funktionsparameter verwenden,
welche drüben als PAnsiChar und PWideChar behandelt werden, da die LongString intern kompatibel dazu sind.
(Zeiger auf ersten Char, nicht auf die davorliegenden Verwaltungsdaten, und hinten immer gefolgt von zwei #0#0)


Erstmal Variant versus OleVariant.
* Variant kann auch einige delphi-spezifische Typen enthalten, wie z.B. LongStrings ala AnsiString und UnicodeString
* der OleVariant kennt nur die standardmäßigen Typen des OLE32/OLEAuth, also so, wie Windows einen "Variant" definiert hat
* die Übergabe an externe Funktionen, welche Delphi nicht kennen, sollte somit nur via OleVariant erfolgen (nicht Variant)

Variant hat definitiv keine Referenzzälung (selbst wenn es einige interne Typen könnten).

Die LongStrings haben eine Referenzzählung, also Kopieren/Zuweisen von Variablen, sowie Übergabe an Property und Nicht-Const-Parameter geht extrem schnell und ressourcenschonend (CPU-Last und Arbeitsspeicher).

WideString (BSTR) bietet seit XP eine Referenzzälung, aber Delphi hat das nicht implementiert,
somit wird immer der komplette Inhalt kopiert, über einem fremden Speichermanager.

OleVairant nutzt intern nur den WideString, wenn man ihm z.B. einen String bzw. UnicodeString zuweist.

paule32.jk 7. Aug 2024 16:13

AW: CE 12: constructor und Free vertragen sich nicht mit den destructor ?
 
ich weiß auch gerade nicht so recht, ob FPC auch supported werden soll.
Auf der einen Seite kann man mit FPC kommerzielle Anwendungen credenzen - allerdings ist FPC so nen gefukkel aus allem möglichen Platformen (und natürlich richtig fätte .Exe cutables erzeugend).

Mit Delphi CE 12 kann ich auch Programme erstellen, aber hier habe ich auch ein gefukkel (also erstmal in der Anfangsphase).
Aber: es werden DLL Bibliotheken besser unterstützt.
Aber: die CE ist restriktiv - Du kannst sie als Testversion einsetzen, soll aber keine Testversion sein ?
Ich kann aber diese Version nicht einsetzen, da ich 80 Euro pro Monat bekomme (für Schnukkelkram und Körperpflege).
im Jahr würde das 960 Euro bedeuten.
Aber: wenn ich damit 5000 Euro Umsatz machen würde, werden die:
Code:
  5.000
-   960
-------------
= 4.040 Euro
Aber: dieser Rest wird angerechnet ? - auf was ?

Ich bin nicht direkt angestellt, sondern nur untergebracht.
Muss ich da dann den Umsatz meiner Firma mit einfließen lassen ?

Worauf ich aus bin:
- lohnt sich der "unentgeltliche" Aufwand: also kann man solche Gedanken gebrauchen - also die Anbindung Delphi/FPC => GNU C++ => FPC/Delphi ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz