Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   CPort Komponente - Fehler bei Port-Enumeration (https://www.delphipraxis.net/207889-cport-komponente-fehler-bei-port-enumeration.html)

TERWI 12. Mai 2021 11:43

CPort Komponente - Fehler bei Port-Enumeration
 
Seit vielen Jahren nutze ich schon CPort-Compo ohne Probleme.
Nun zickt Sie rum ... das Problem:

Mein Proggie liest aus einer INI-Datei die Vorgabe für den COM-Port ala 'COM3'.
Mit "EnumComPorts(TStrings)" (in CPort) lese ich die Liste der verfügbaren Ports und prüfe ob es die Vorgabe gibt.
Falls JA, Comport setzen, öffnen, auf connected prüfen und ab die DatenLuzie ... Zum Schluss ComPort schließen und gut.
Wenn ich mich nicht irre, gibt es dieses Tool schon seit D6. Ob ich das schon mal mit 10.3 am Start hatte ... weiß nicht mehr.

"Vorgabe nicht in den COM-Liste" lautet meine Fehlermeldung - ich bekomme aber COM3 bei Auflistung angezeigt ?!
Beides ist groß geschrieben, also müsste das mit '=' funzen.
Also mal mit CompareStr, CompareText, SameStr, SameText probiert: Immer ungleich (Ergebnis 1, größer).
Erst mit AnsiCompareStr gab es ein Match. Gut, OK, weiter im Programm.

Alles läuft so weit mit dem alten Source: Freude kommt auf, wenn da nicht gelegentlich (NCHT IMMER) diese AV beim beenden des Proggies wäre.
Irgendwas geht irgendwo in die Uhr weil von ungültiger Adresse "gelesen" wird. HÄ ?
Das hatte ich schon mal als ich auf einen versehentlich schon freigegebenen Record schreiben wollte.
Wie gesagt, die AV kommt nicht immer, sondern nur ca. 5-8 von 10x. Sehr kurios !

Das wars aber nicht ! 3 Tage hab ich nun gesucht und bin zu dem Schluss gekommen:
Es ist die procedure EnumComPorts(Ports: TStrings);

Ich hatte mich wieder dem Portvergleich gewidmet und festgestellt, dass das Ergebnis der Stringliste (HIER) in jedem Eintrag nicht 4, sondern 9 Zeichen enthält:
Die Portbezeichnung als 4 Buchstaben plus 5 Nullen dahinter.

Das stört bei der Ausgabe so nicht weiter, beim Vergleich aber eben schon.
Nimmt man die Nullen raus, funzt alles wieder wie gewünscht und auch keine AV mehr.

Hier scheint es offensichtlich, das ComPort.Open den vermeintlich ungültigen Namen noch akzeptiert (Port wird anstandslos geöffnet), aber innerhalb ComPort.Close scheint sich da irgendwas an den zusätzlichen Nullen zu stören.
Ich habe bisher noch nicht herausgefunden was/wo das sein könnte ...

Und woher kmmen die Nullen ?
DataLen gibt mir hier immer "10" aus und soll lt. MS-Docs die Anzahl Zeichen in Data angeben.
Da steht auch nichts von 'include the terminating null character' - also 6 Zeichen zuviel.
M. E. n. ein Fehler seitens Windoof (hier 8.1).

Ich hab die procedure mal ein wenig abgeändert - nu lüpp dat:

Delphi-Quellcode:
procedure EnumComPorts(Ports: TStrings);
var
  KeyHandle: HKEY;
  ErrCode, Index: Integer;
  ValueName, Data: array[0..256] of char; // string;
  ValueLen, DataLen, ValueType : DWORD;
begin
  if NOT Assigned(Ports) then exit;
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                   'HARDWARE\DEVICEMAP\SERIALCOMM',
                   0,
                   KEY_READ,
                   KeyHandle) <> ERROR_SUCCESS) then exit;
  try
    Index := 0;
    repeat
      ValueLen := 256;
      DataLen := 256;
      ErrCode := RegEnumValue(KeyHandle,
                              Index,
                              @valuename, // PChar(ValueName),
                              ValueLen,
                              nil,
                              @ValueType,
                              PByte(@Data), // PByte(PChar(Data)),
                              @DataLen);
      if ErrCode = ERROR_SUCCESS then
      begin
        Ports.Add(Data); // TmpPorts.Add(Data);
        Inc(Index);
      end;
    until (ErrCode <> ERROR_SUCCESS) ;
  finally
    RegCloseKey(KeyHandle);
  end;
end;

himitsu 12. Mai 2021 12:33

AW: CPort Komponente - Fehler bei Port-Enumeration
 
Anzahl der "Byte"

(4 + 1) * 2 = 10 für Unicode (2 Byte pro Char)


Das Name in Char, aber die Data in Byte.

Allerdings willst du doch bestimmt den Name speichern? (hab grad keinen COM-Port dran und weiß seh nicht was in Data steht)



Ach ja, weil sind keine Strings, sondern statische Arrays:
Delphi-Quellcode:
// PChar(@ValueName),

// PByte(PChar(@Data)),
Wovei die PChar-Casts unnötig sind, da ein Zeiger auf einen Char ein bereits PChar ist. :angle:

dummzeuch 12. Mai 2021 13:29

AW: CPort Komponente - Fehler bei Port-Enumeration
 
Zitat:

Zitat von himitsu (Beitrag 1489274)
Ach ja, weil sind keine Strings, sondern statische Arrays:
Delphi-Quellcode:
// PChar(@ValueName),

// PByte(PChar(@Data)),
Wovei die PChar-Casts unnötig sind, da ein Zeiger auf einen Char ein bereits PChar ist. :angle:

@ArrayOfChar ist kein PChar, das gilt nur für @ArrayOfChar[Index]

Das gibt sogar einen Comile-Error, wenn Typed @ Operator eingeschaltet ist, sonst wird das nicht geprüft.

himitsu 12. Mai 2021 13:43

AW: CPort Komponente - Fehler bei Port-Enumeration
 
OK, den "strengen" Compiler vergessen, dann eben mit PChar Cast, oder einfach [0] hinten dran. :angle:


Du darfst gern, @StatischesArrayOfChar[0] anstatt @StatischesArrayOfChar machen, aber es macht keinen Unterschied (vom Speichermanagement her ... OK, die Typprüfung mal außen vor).

@AnfangDesStatischenArray (wo der erste Char liegt) = @ErstesCharImArray[0]


Aber "immer" mit [0] ist nicht falsch und würde zumindestens für statisches Array und dynamisches Array im Quellcode den selben Code verwenden, und die Typprüfung ist auch froh.
(weniger Varianten = weniger potentielle Fehler)

TERWI 12. Mai 2021 17:02

AW: CPort Komponente - Fehler bei Port-Enumeration
 
PChar muss sein - der Compiler meckert, weil für Data ein PByte von RegEnumValue gefordert.
Bei Valuename passt das mit @.

Das it den 10 byte für ein WChar könnte Sinn machen ....
Data einzeln "durchbuchstabiert" in der org. Version ergibt z. B.
C O M 3 0 0 0 0 0 0 (ein Ansi-String)

Um in Wchar zu wandeln müsste es doch so aussehen ?:
0 C 0 O 0 M 0 3 0 0 (mit Null als Stringende)


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

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