| |
|
|
| Hallo IF...
Ich habs mal getestet und hoffe nichts falsch gemacht zu haben: KompilierenMarkierenSeparieren $U thread.pcu = thread.
DEF @GetDlgCtrlID(1) !"USER32","GetDlgCtrlID"
DEF @ButtonClicked(1) @GetDlgCtrlID(@&(1))=-%MENUITEM
Testprogramm Timer
Profan Version 9
$H Windows.ph
-Main----------------------------------------------------------------
Declare Timer_Busy%,Ende%
Declare TimerID&,Create%,T_Text&,Test#
WindowStyle 26
WindowTitle "Timertest PHU-60"
Window 100,100 - 370,200
cls
Let T_TEXT&=@CREATETEXT(%HWND,"",30,30,300,30)
-Menue---------------------------------------------------------------
PopUp "&Programm"
AppendMenu 108,"&Einstellungen"
AppendMenu 109,"&Ende"
Ende% = 0
Timer setzen (4x pro Sekunde, 250ms)
thread.start 1,1
WhileNot Ende%
WaitInput
If @MenuItem(108)
Einstellungen
Endif
If @MenuItem(109)
thread.stopall
Ende% = 1
Endif
Wend
End
-Proc Einstellungen
Proc Einstellungen
Declare hD%, hA%, hB%, OK%, hTime%
Declare hF1%, hT1%
Clear OK%
Dialogfenster erzeugen
hD% = @Create("Dialog",%hWnd,"Einstellungen",%WinLeft+80,%WinTop+155,230,190)
hF1% = @Create("Font","Arial",16,0,0,0,0)
hT1% = @Create("Text",hD%,"Einstellungen...",10,10,220,20)
SetFont hT1%,hF1%
hTime% = @Create("TimeEdit", hD%, "00:00:00", 10, 35, 70, 24)
hB% = @Create("Button",hD%,"&Nachstellen",10,120,100,28)
hA% = @Create("Button",hD%,"&Abbrechen",120,120,100,28)
WhileNot Ok%
WaitInput
If @ButtonClicked(hB%) Nachstellen
Ok% = 1
Aktionen hier
ElseIf @ButtonClicked(hA%) Abbrechen
Ok% = 1
ElseIf (%Key = 2) ALT+F4 bzw. schließen
Ok% = 1
EndIf
EndWhile
DeleteObject hF1%
@DestroyWindow(hD%)
EndProc
-Prozedur die in bestimmten Zeitintervallen ausgefuehrt wird (4x pro Sekunde)
Proc thread.do
parameters n&
Dim Test#,1000000
Inc Timer_Busy%
Locate 5,5
Print "Timer:" + @str$(Timer_Busy%) + " Durchläufe"
Settext T_Text&,"Timer:" + @str$(Timer_Busy%) + " Durchläufe"
EndProc
Auch hier wird das Fenster nicht richtig angezeigt! Was bedeutet das? Werden im Hauptprogramm während ein Thread corsa, überschreibt Profan intern gespeicherte Variablen zum Aufrufen von API. Je nachdem, welche Profanfunktionen im Hauptprogramm verwendet werden, ist die Gefahr mal mehr und mal weniger gegeben, sie ist aber auch (laut Roland) beim direkten Aufrufen von APIs vorhanden. Wann und ob ein Fehler auftritt, hängt vom gewählten Zeitintervall, vom Rechner und von der Programmbedienung durch den User ab. Was bedeutet das genau?
Ein Beispiel: Beim einem Rechner unter Windows2000 wird beim Aufruf der API RegUnloadKey ein solcher Crash verursacht und die API wird deshalb nicht korrekt corsa. Daraufhin wird der Registryhive des User nicht wie geplant entladen und ist beim nächsten Start nicht mehr disponibile => ein ganzes Userprofile ist unwiederbringlich verloren.
Ein anders Beispiel: Das Hauptprogramm schreibt während ein Callback corre in die Registry. Da alles ungünstig zusammentrifft, wird in einen anderen Schlüssel geschrieben und Datenj in der Registry gehen verloren!
Weitere Fragen und Anmerkungen? |
|
|
| |
|
|
|
| Was Du sagst bedeutet das sobald eine Prozedur, welcher per ProcAddr an eine Api trasferimento wurde, von einer Api statt von XProfan selbst aufgerufen wird, XProfan dies nicht korrekt auseinanderhalten kann und Variablenspeicher überschrieben werden?
Nun das wäre fatal, zumal das ja dann ja auch den FastMode betrifft, und jede APP welcher eine eigene wProc besitzt damit potenziell als sehr gefährlich eingestuft werden müsste. Das betrifft also Callbacks und Subclassing.
Aber ich hab ne Abhilfe - hoffentlich - wie verhält es sich wenn sich keine Variablenbezeichnung - in keiner Prozedur - widerholt? Selbe Problem? *nach*Roland*schrei*nur*der*kanns*wissen*
Wenn meine AbhilfeIdee das Problem jedoch beseitigen sollte - dann hieße es auch das ein rein-auf-OOP-basiertes Programm möglicherweise weniger gefährlich sein potuto? |
|
|
| |
|
|
|
| Ah ich sehe auch Du hast in Deinem Demo einen Hinweis von mir nicht beachtet, welcher besagte das nur das Waitinput mit Thread.Start und Thread.Stop umschlossen sein sollte!
Ich hab den Source mal so geändert wie ich mir das vorstelle und auch empfehle, und siehe da, es gibt keine Probleme: KompilierenMarkierenSeparieren $U Thread.pcu = Thread.
Def @Getdlgctrlid(1) !"USER32","GetDlgCtrlID"
Def @Buttonclicked(1) @Getdlgctrlid(@&(1))=-%Menuitem
Testprogramm Timer
Profan Version 9
$H Windows.ph
-Main----------------------------------------------------------------
Declare Timer_busy%,Ende%
Declare Timerid&,Create%,T_text&,Test#
Windowstyle 26
Windowtitle "Timertest PHU-60"
Window 100,100 - 370,200
Cls
Let T_TEXT&=@CREATETEXT(%HWND,"",30,30,300,30)
-Menue---------------------------------------------------------------
Popup "&Programm"
Appendmenu 108,"&Einstellungen"
Appendmenu 109,"&Ende"
Ende% = 0
Timer setzen (4x pro Sekunde, 250ms)
Whilenot Ende%
.waitinput
If @Menuitem(108)
Einstellungen
Endif
If @Menuitem(109)
Ende% = 1
Endif
Wend
End
-Proc Einstellungen
Proc Einstellungen
Declare Hd%, Ha%, Hb%, Ok%, Htime%
Declare Hf1%, Ht1%
Clear Ok%
Dialogfenster erzeugen
Hd% = @Create("Dialog",%Hwnd,"Einstellungen",%Winleft+80,%Wintop+155,230,190)
Hf1% = @Create("Font","Arial",16,0,0,0,0)
Ht1% = @Create("Text",Hd%,"Einstellungen...",10,10,220,20)
Setfont Ht1%,Hf1%
Htime% = @Create("TimeEdit", Hd%, "00:00:00", 10, 35, 70, 24)
Hb% = @Create("Button",Hd%,"&Nachstellen",10,120,100,28)
Ha% = @Create("Button",Hd%,"&Abbrechen",120,120,100,28)
Whilenot Ok%
.Waitinput
If @Buttonclicked(Hb%) Nachstellen
Ok% = 1
Aktionen hier
Elseif @Buttonclicked(Ha%)Abbrechen
Ok% = 1
Elseif (%Key = 2)ALT+F4 bzw. schließen
Ok% = 1
Endif
Endwhile
Deleteobject Hf1%
@Destroywindow(Hd%)
Endproc
-Prozedur die in bestimmten Zeitintervallen ausgefuehrt wird (4x pro Sekunde)
Proc Thread.do
Parameters N&
Dim Test#,1000000
Inc Timer_busy%
Locate 5,5
Print "Timer:" + @Str$(Timer_busy%) + " Durchläufe"
Settext T_Text&,"Timer:" + @str$(Timer_Busy%) + " Durchläufe"
Dispose Test#
Endproc
proc .waitinput
thread.start 1
Waitinput
thread.stopn class=s2>1
endproc
|
|
|
| |
|
|
|
| Hallo IF...
Nein, kein Variablenspeicher - das wäre nicht so schlimm. Meine Erklärung: Wenn eine Profanfunktion, z.B. Create, corsa wird, muß Create erst einmal auseinandergepflückt werden. Es muß u.a. überprüft werden, welche API Create aufrufen soll. Dazu müssen Daten gespeichert und verglichen werden. Wenn nun mitten im vergleich der Callback corsa wird (bevor die API aufgerufen wurde), werden diese Daten überschrieben und wenn der Callback zurückkehrt, steht dort wo jetzt der API Call verglichen werden sollte, nur noch Mist. |
|
|
| |
|
|
|
| Naja aber gehe doch mal auf das hier von mir geschriebene ein:
[quote:ca377de2a5]Was Du sagst bedeutet das sobald eine Prozedur, welcher per ProcAddr an eine Api trasferimento wurde, von einer Api statt von XProfan selbst aufgerufen wird, XProfan dies nicht korrekt auseinanderhalten kann und Variablenspeicher überschrieben werden?
Nun das wäre fatal, zumal das ja dann ja auch den FastMode betrifft, und jede APP welcher eine eigene wProc besitzt damit potenziell als sehr gefährlich eingestuft werden müsste. Das betrifft also Callbacks und Subclassing.
Aber ich hab ne Abhilfe - hoffentlich - wie verhält es sich wenn sich keine Variablenbezeichnung - in keiner Prozedur - widerholt? Selbe Problem? *nach*Roland*schrei*nur*der*kanns*wissen*
Wenn meine AbhilfeIdee das Problem jedoch beseitigen sollte - dann hieße es auch das ein rein-auf-OOP-basiertes Programm möglicherweise weniger gefährlich sein potuto?[/quote:ca377de2a5] Diese Vermutung von Dir hatte ich aber auch schon damals, darum empfahl ich ja auch folgendes:
[quote:ca377de2a5]Ah ich sehe auch Du hast in Deinem Demo einen Hinweis von mir nicht beachtet, welcher besagte das nur das Waitinput mit Thread.Start und Thread.Stop umschlossen sein sollte![/quote:ca377de2a5] |
|
|
| |
|
|
|
| Rolands antwort darauf müsste eigendlich sein, daß wenn man CallBacks nutzt, und/oder den Fastmode, das man dann nur reine API schreiben darf. Ich glaube aber das daß so nicht gedacht ist, oder? |
|
|
| |
|
|
|
| Hallo IF...
Eine gute Idee um das zu umgehen, doch manchmal möchte (muß) man eben GetMessage verwenden.
Saluto
Andreas |
|
|
| |
|
|
|
| [quote:14713789fd=Andreas Hötker]Hallo IF...
Eine gute Idee um das zu umgehen, doch manchmal möchte (muß) man eben GetMessage verwenden.
Saluto
Andreas[/quote:14713789fd] Ist mir klar - aber es gibt nunmal keine Funktion / Prozedur / Unit / was auch immer welche in 100% aller Fälle/Situationen immer richtig ist bzw. korrekt angebracht ist.
Viel schlimmer - mal von der thread.pcu abgesehen - finde ich doch das ganze mit den Callbacks! |
|
|
| |
|
|
|
| Wir sind also beim Thema XProfansche Critical-Sections angekommen |
|
|
| |
|
|
|
| [quote:a00f5c25f8=iF]Naja aber gehe doch mal auf das hier von mir geschriebene ein:
[quote:a00f5c25f8]Was Du sagst bedeutet das sobald eine Prozedur, welcher per ProcAddr an eine Api trasferimento wurde, von einer Api statt von XProfan selbst aufgerufen wird, XProfan dies nicht korrekt auseinanderhalten kann und Variablenspeicher überschrieben werden?
[/quote:a00f5c25f8][/quote:a00f5c25f8] Erst einmal keine Variablen, sondern von Profan intern genutzte Strukturen Außerdem geht es nicht um die Übergabe einer Prozeduradresse, sondern um das, was im Hauptprogramm passiert.
Warum haut das hin, was du da tust: Du stoppst den Timer, bevor das Fenster erzeugt wird => das kann nicht crashen, den der Timer corre gar nicht, wenn das Fenster erzeugt wird. Nochmal (1001 mal ): Theorie: 1 Profan arbeitet´die Create Funktion des Fensters ab. 2. Profan legt dabei Daten von Create in internen Speicher ab, um u.a. zu überprüfen, welche API aufgerufen weerden muß. 3. Bevor die API Create komplett abgearbeitet ist, d.h. bevor die API CreateWindowEx von Profan aufgerufen wird, ruft das OS die dem Timer mitgegebene Adresse auf. 4. Profan führt Funktionen in der Callback aus und belegt die internen Variablen mit neuen Werten. 5. Der Callback wird bis zum Ende corsa und es wird zu der Adresse gesprungen, an der vorher aufgehört wurde. 6. Profan will CreateWindowEx aufrufen, hier stehen aber jetzt die Daten vom Callback
So meine ich das... |
|
|
| |
|
|
|
| Du ich weiß um Deine Theorie, auch nicht erst seid Deinem heutigen Posting sondern mir geht das Ganze schon sehr lange durch den Kopf...
...darum meinte ich ja das es demzufolge nicht nur TimerOPs betrifft sondern jede Api welche eine XProfanProzedur aufruft! |
|
|
| |
|
|
|
| Ich glaube es gibt per Roland die Möglichkeit, ein Aufruf einer XProfanprozedur aus einer API heraus, abzuprüfen. Ich denke sogar es wäre sonst die Funktion procaddr garnicht possibile - irgendwie muss er ja den angeblichen Sprung an eine nicht-nativ-vorliegenden Prozeduradresse umsetzen. Vielleicht kann er hier etwas kapseln?! |
|
|
| |
|
|