Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler (https://www.delphipraxis.net/205511-winapi-aufruf-geht-release-fassung-problemlos-bei-debug-spuckt-er-fehler.html)

Der schöne Günther 17. Sep 2020 21:51

WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler
 
Liste der Anhänge anzeigen (Anzahl: 3)
Ich rufe die Windows-Routinen PowerCreateRequest und PowerSetRequest auf.

Lasse ich meine Anwendung als "Release" laufen, funktioniert alles wie gehabt. In "Debug" hingegen wirft mir die WinApi-Routine PowerSetRequest einen System Error 50 - The request is not supported um die Ohren.

Wenn ich in der "Debug-Fassung" die Optimierungen einschalte, dann ist in der Debug-Fassung der Fehler auch weg.

Ich habe absolut keine Ahnung was das verursacht, wo ich ansetzen muss damit es auch in Debug vernünftig läuft. FastMM meldet keine Speicherfehler, Bereichsüberschreitungen gibt es auch keine. Mein Verdacht ist der variante Record welcher per Zeiger übergeben wird, aber beweisen kann ich es nicht.

Kompletter Quellcode im Anhang.

Das Problem tritt sowohl bei Delphi 10.0 Seattle, als auch bei 10.4 Sydney auf. Ich konnte nur Win32 testen, Win64 nicht.

himitsu 17. Sep 2020 22:23

AW: WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler
 
In Windows sind ENUMs oft/meistens INT groß,
In Delphi aber so klein, wie möglich, womit dein TPowerRequestType also nur ein Byte ist, anstatt 4 Byte.

Hier kommt es dann drauf an, wie die Speicherausrichtung und Position der Variablen arbeiten, also ob hinter diesem Byte zufällig noch 3 ungenutzte Bytes liegen, gefüllt mit Nullen,
was natürlich von den Einstellungen z.B. der Codeoptimierung abhängt.
Im Debug-Modus liegen Variablen oft auf dem Stack/Heap, damit der Debugger eine feste Stelle zum Auslesen hat, während es im Release auch in die Register wandern kann.

Für TPowerRequestType also unnbedingt mit
Delphi-Quellcode:
{$MinEnumSize 4}
arbeiten. (leider gibt es kein MinimumSetSize, für sowas braucht man dann eventuell ein
Delphi-Quellcode:
, dummy=31);
am Ende)


Und beim TReasonContext entweder ein passendes
Delphi-Quellcode:
{$ALIGN 4}
(Win32 ... Win64 eventuell anders) oder mit PACKED RECORD und eventuellen Füll-Bytes arbeiten,
denn je nach DelphiVersion und Zielplattform ändern sich Grundeinstellungen von $ALIGN schonmal.


PS: Der Typ von POWER_REQUEST_TYPE wird in der Online-Docu nicht genannt, (aber erfahrungsgemäß wird es zu 99.9995% ein INT, UINT oder DWORD sein)
hier kannst dir nur das Windows-SDK runterladen und in der unten genannten Header-Datei "winbase.h" (C++) nachsehn, falls keine andere Quelle so nett ist und das nennt. Bei Google suchenPOWER_REQUEST_TYPE

Der schöne Günther 18. Sep 2020 08:29

AW: WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler
 
Zitat:

Zitat von himitsu (Beitrag 1473775)
In Windows sind ENUMs oft/meistens INT groß,
In Delphi aber so klein, wie möglich, womit dein TPowerRequestType also nur ein Byte ist, anstatt 4 Byte

(...)

Für TPowerRequestType also unnbedingt mit {$MinEnumSize 4} arbeiten.

Das ist es!

Vielen Dank. 🎉 Ich glaube da wäre ich nie drauf gekommen.

KodeZwerg 18. Sep 2020 09:03

AW: WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler
 
Zitat:

Zitat von himitsu (Beitrag 1473775)
Der Typ von POWER_REQUEST_TYPE wird in der Online-Docu nicht genannt

PowerSetRequest führt zu REASON_CONTEXT was ich als POWER_REQUEST_TYPE auffasse.

Zumindest würde ich es so verstehen.

//edit, falsch verstanden beim nochmaligen lesen.
Zitat:

PowerRequestDisplayRequired
The display remains on even if there is no user input for an extended period of time.

PowerRequestSystemRequired
The system continues to run instead of entering sleep after a period of user inactivity.

PowerRequestAwayModeRequired
The system enters away mode instead of sleep in response to explicit action by the user. In away mode, the system continues to run but turns off audio and video to give the appearance of sleep.

PowerRequestExecutionRequired
The calling process continues to run instead of being suspended or terminated by process lifetime management mechanisms. When and how long the process is allowed to run depends on the operating system and power policy settings.

On systems not capable of connected standby, an active PowerRequestExecutionRequired request implies PowerRequestSystemRequired.
Also so etwas hier in etwa:
Delphi-Quellcode:
TPowerRequestType = (
  PowerRequestDisplayRequired = 0,
  PowerRequestSystemRequired = 1,
  PowerRequestAwayModeRequired = 2,
  PowerRequestExecutionRequired = 3);

dummzeuch 18. Sep 2020 09:26

AW: WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler
 
Zitat:

Zitat von KodeZwerg (Beitrag 1473782)
Zitat:

Zitat von himitsu (Beitrag 1473775)
Der Typ von POWER_REQUEST_TYPE wird in der Online-Docu nicht genannt

PowerSetRequest führt zu REASON_CONTEXT was ich als POWER_REQUEST_TYPE auffasse.

Zumindest würde ich es so verstehen.

Noe, REASON_CONTEXT ist ein Record, POWER_REQUEST_TYPE ist ein Enum. Und dessen Größe wird leider nicht angegeben, aber in der WinAPI ist sowas fast immer 32 Bit. (Ist mir aber damals nicht aufgefallen, als ich darüber geblogt habe. Das habe ich gerade korrigiert.)

KodeZwerg 18. Sep 2020 09:37

AW: WinApi-Aufruf geht in "Release"-Fassung problemlos, bei "Debug" spuckt er Fehler
 
Ich war zu voreilig beim posten, hab es bereits korrigiert, sorry für spam.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:22 Uhr.

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