HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0513
cvonexit25解決


cv

リンク

2010/5/13(Thu) 18:04:45|NO.32636

hsp3clでonexitが使用できません。
別の方法を教えてください。



この記事に返信する


荒河

リンク

2010/5/15(Sat) 21:22:31|NO.32656

ほんとだ、使えないね



cv

リンク

2010/5/16(Sun) 01:41:20|NO.32659

思いついた方法:
メインプロセス(演算主体)とサブプロセス(描画、メインプロセス監視)をつくる。
メインプロセスの変数をサブプロセスが読み取り、メインプロセスが終了すると
その変数を保存する。

やり方を教えてください。



pizza

リンク

2010/5/19(Wed) 03:32:19|NO.32717

#deffuncのonexitは使えるみたいですがどうでしょう?


#runtime "hsp3cl" #module #deffunc _onexit onexit mes "終了処理" return #global



cv

リンク

2010/5/19(Wed) 04:13:15|NO.32718

stopで殺すならいいようですが、Alt+F4とかで殺すとうまくいきません。



pizza

リンク

2010/5/19(Wed) 14:25:15|NO.32720

ちょくとさんのhscallbk.dllを使ってます。



#runtime "hsp3cl" #include "hscallbk.as" #include "kernel32.as" #define CTRL_C_EVENT 0 #define CTRL_BREAK_EVENT 1 #define CTRL_CLOSE_EVENT 2 #uselib "" #func HandlerRoutine "" int #module #deffunc __cleanup onexit gosub *lb_cleanup@ return #global setcallbk proc, HandlerRoutine, *lb_HandlerRoutine SetConsoleCtrlHandler varptr(proc), 1 stop *lb_HandlerRoutine ct = callbkarg(0) //ユーザーがコンソールを閉じた if ct == CTRL_CLOSE_EVENT { gosub *lb_cleanup return 1 } return 0 *lb_cleanup //終了処理 return



cv

リンク

2010/5/20(Thu) 04:46:47|NO.32724

うまくいきました。
ありがとうございました。

追記:できるなら解説をお願いします。



pizza

リンク

2010/5/20(Thu) 05:09:38|NO.32725

SetConsoleCtrlHandler
http://msdn.microsoft.com/ja-jp/library/cc429733.aspx

HandlerRoutine
http://msdn.microsoft.com/ja-jp/library/cc429519.aspx

setcallbkとcallbkargについてはhscallbk.dllのreadme.txtとサンプルを参照してください。



cv

リンク

2010/5/21(Fri) 04:31:08|NO.32727

えーと、TRUEを返すのではなく、ExitProcessを呼び出して(?)自分から終了
させるにはどうしたらいいのでしょうか。



pizza

リンク

2010/5/21(Fri) 15:16:55|NO.32728


ExitProcess 0

と書くだけで良いはずですが?だめですか?

FALSEを返せば規定のハンドラがプロセスを終了するとあるのでreturn 0にするだけで良いかも?



cv

リンク

2010/5/22(Sat) 04:48:51|NO.32733

あー、kernel32.asを#includeすると関数は普通に使用できたんだ。
すいません。考えたら簡単な話でした。

あと、kernel32.asにある関数かない関数かの判断はkernel32.asを見るしかないのですか?



cv

リンク

2010/5/22(Sat) 04:55:22|NO.32734

すいません、結果書き忘れました。
ExitProcessでもreturn 0でもOKでした。



pizza

リンク

2010/5/22(Sat) 05:10:43|NO.32735

MSDNの関数リファレンスで
http://msdn.microsoft.com/ja-jp/library/cc429099.aspx

下のほうにある対応情報のインポートライブラリがKernel32.libになっていればkernel32.asでほぼ使用できるはずです。



cv

リンク

2010/5/22(Sat) 15:44:06|NO.32739

ほんとありがとうございました。
勉強になりました。



cv

リンク

2010/6/8(Tue) 18:51:19|NO.33138

exe化すると、Error16とか、VBがなんだとか、Error29が頻発します。
スクリプト上からもたまに。
助けてください。



pizza

リンク

2010/6/10(Thu) 03:41:21|NO.33181

ソースを見てないので原因はわかりせんがerror16と29は下記のようになっています。


16 "パラメータの数が多すぎます"
命令に指定されたパラメータの数が多すぎる時に表示されます。

29 "スタック領域のオーバーフローです"
サブルーチン呼び出しや、式の評価の処理中にスタックが破壊された 場合に表示されます。通常、表示されることはありません。 これが表示される場合は、システムに致命的なエラーが発生したことを 示しています。

>VBがなんだとか
VB用のプラグイン等を使用しているなら、必要なDLL(OCX)をEXEと同じフォルダに入れてみてください。



cv

リンク

2010/6/10(Thu) 21:23:40|NO.33197

えーと、どこにもそういったものは見当たりません。
if{}を使用していることが原因なのでしょうか。
あと、VBがなんだとかっていうのは、日の丸にばつのマークとともに、なんとかError!って
怒られるということです。
いちおう、スクリ貼っておきます。

#runtime "hsp3cl" #include "hsp3clmod.as" #include "longint.as" #include "d3m.hsp" #module #deffunc IsPrimeLocal var D f=0 A=D*D B=(D+1)*(D+1) *pe if IsPrime(A)=1:f=1:return f A++ if A!B:goto *pe return f #global #include "hscallbk.as" #include "kernel32.as" #define CTRL_C_EVENT 0 #define CTRL_BREAK_EVENT 1 #define CTRL_CLOSE_EVENT 2 #uselib "" #func HandlerRoutine "" int #module #deffunc __cleanup onexit gosub *lb_cleanup@ return #global setcallbk proc, HandlerRoutine, *lb_HandlerRoutine SetConsoleCtrlHandler varptr(proc), 1 #include "pm.as" #include "am.as" clInit clclear clSetCursor -1 clWidth 80,15 notesel M randomize noteload "Prime_n.txt" C=longint(M)-10 mes mes " Investigation will start." mes D=d3timer()+1000 *Enter //gm_String@ =str(C) val=d3getfps() C++ IsPrimeLocal C if stat = 1{ if d3timer()>=D{ clpos 0,3 mes " n^2= "+C*C mes mes " n="+C+" and before is OK!" mes " fps "+strf("% 6d",val) D=d3timer()+1000 } goto *Enter }else{ mes mes " n="+C+" is not OK!" mes " n^2="+str(C*C) mes " (n+1)^2="+B goto *endn } *endn mes " Halted." sleep -1 *lb_HandlerRoutine gosub *lb_cleanup return 0 *lb_cleanup //終了処理 A=str(longint(C-10)) bsave "Prime_n.txt",A return



cv

リンク

2010/6/10(Thu) 21:26:48|NO.33201

訂正:
33,34行目を削除。(#include)
hsp3clmodとlongintはググってください。



ANTARES

リンク

2010/6/11(Fri) 03:54:15|NO.33208

 少なくとも数分くらいは特にエラーもなく動いているようですが?
Prime_n.txtの内容を書いてください。

 エラーと関係あるかどうかわかりませんが
誤:bsave "Prime_n.txt",A
正:bsave "Prime_n.txt",A,strlen(A)
または
正: notesel A: notesave "Prime_n.txt"



cv

リンク

2010/6/11(Fri) 18:56:51|NO.33211

Prime_n.txt

141035626
困っているのは、出るときと出ないときがあることです。



ANTARES

リンク

2010/6/12(Sat) 01:06:06|NO.33214

 デバッグ・ウィンドウを表示して
コマンド・プロンプト・ウィンドウをアクティブにして
Ctrl-Cを押したら、一度だけ
「A=str(longint(C-10))」でスタック・オーバーフローが出ましたが、
その後は何度同じことをやっても出ません。
再現性の低いエラーはやっかいです。
エラー原因もちょっと見当がつきません。

 dllを減らすとか、#includeの順序を変えるとかすると、
ひょっとしたら直るかもしれませんが、
直ったか否かの確認すらとりづらいのが痛いところです。



cook

リンク

2010/6/12(Sat) 10:30:41|NO.33215

以下のように一行追加したらエラーが頻発するようになりました。
おそらくHSPはSetConsoleCtrlHandlerには対応していないのだと思います。
コールバックやウインドウメッセージと違い、このハンドラルーチンがどのようなときに
呼び出されるかは完全に予測不可能なので、例えばインタプリタのコードの解釈途中で
呼び出されても大丈夫なようには出来ていないのだと思います。

*lb_cleanup //終了処理 assert 0 //追加 A=str(longint(C-10))



cook

リンク

2010/6/12(Sat) 11:40:56|NO.33216

解決策を示すの忘れてました。
ようはhscallbkを使わずに、終了を検知すればいいので以下の方法で良いと思います。


#runtime "hsp3cl" #include "hsp3clmod.as" #include "longint.hsp" #include "d3m.hsp" #module #deffunc IsPrimeLocal var D f=0 A=D*D B=(D+1)*(D+1) *pe if IsPrime(A)=1:f=1:return f A++ if A!B:goto *pe return f #global #include "kernel32.as" #define CTRL_C_EVENT 0 #define CTRL_BREAK_EVENT 1 #define CTRL_CLOSE_EVENT 2 #uselib "" #func HandlerRoutine "" int #module #deffunc __cleanup onexit gosub *lb_cleanup@ return #global //追加 proc=$000001b8,$0000a300,$04c20000,$00000000 lpoke proc,6,varptr(endflag) VirtualProtect varptr(proc),16,0x40,varptr(endflag) endflag=0 SetConsoleCtrlHandler varptr(proc), 1 clInit clclear clSetCursor -1 clWidth 80,15 notesel M randomize noteload "Prime_n.txt" C=longint(M)-10 mes mes " Investigation will start." mes D=d3timer()+1000 *Enter //gm_String@ =str(C) gosub *endchk //追加 val=d3getfps() C++ IsPrimeLocal C if stat = 1{ if d3timer()>=D{ clpos 0,3 mes " n^2= "+C*C mes mes " n="+C+" and before is OK!" mes " fps "+strf("% 6d",val) D=d3timer()+1000 } goto *Enter }else{ mes mes " n="+C+" is not OK!" mes " n^2="+str(C*C) mes " (n+1)^2="+B goto *endn } *endn mes " Halted." repeat //追加 sleep 100 gosub *endchk loop *endchk //追加 if endflag:gosub *lb_HandlerRoutine:end return *lb_HandlerRoutine gosub *lb_cleanup return 0 *lb_cleanup //終了処理 A=str(longint(C-10)) bsave "Prime_n.txt",A return



cv

リンク

2010/6/12(Sat) 18:33:08|NO.33219

うまくいきました。cookさん、ありがとうございます。

できれば解説お願いします。



cook

リンク

2010/6/13(Sun) 07:53:39|NO.33238


proc=$000001b8,$0000a300,$04c20000,$00000000 lpoke proc,6,varptr(endflag) VirtualProtect varptr(proc),16,0x40,varptr(endflag) endflag=0 SetConsoleCtrlHandler varptr(proc), 1
hscallbkの代わりにprocには、呼び出されるとendflagに1をいれてTRUEを返す関数をマシン語で入れています。
なので終了しようとするとendflagの内容が1になって終了も拒否します。
あとはループの中でendflagの値が1になっていないかチェックすればいいのです。



cv

リンク

2010/6/13(Sun) 19:28:52|NO.33254

マシン語はわかりませんが、何をしているのかはわかりました。
ありがとうございました。



ONION software Copyright 1997-2021(c) All rights reserved.