XREA.COM Logo XREA.COM Ad

管理人の雑記

47管理人 ★:2007/03/29(木) 23:14:48
マルチスレッド実行を手軽にする

>>45の方法では、引数の数が固定されてしまうし、関数のアドレスなどを埋め込むのが面倒なので、簡単に使えるように関数を作ることに。

スレッド用の機械語コードは動的に生成する。
返り値は、CreateThread()のlpParameter引数で与えられたアドレスに格納することに。
元となるC言語のコードは以下のようになる。
DWORD WINAPI ThreadFunc(LPVOID arg){
DWORD *p=(DWORD *)arg;
*p=((DWORD (WINAPI *)(UINT))(0x11111111))(0x22222222);
return 0;
}

ダンプしたところ、「68 22 22 22 22 b8 11 11 11 11 ff d0 8b 4c 24 04 89 01 33 c0 c2 04 00」となった。
「68 22 22 22 22」の部分が引数をプッシュしている部分である。
これを引数の数だけ繰り返す。右側の引数から順にプッシュしていくらしい。
引数が4バイト以外の時どうプッシュすればいいのかよく分からなかったが、なぜか4バイトのときと同じで構わないらしかった。stdcallの場合の仕様だろうか。
「b8 11 11 11 11」というのが呼び出し先関数のアドレスを設定している部分で、残りは返り値の格納やリターンを行っている部分。
これらを元に、指定の引数を与えて指定アドレスの関数を呼び出すコードを構築する。

返り値の格納先は別途確保しておき、そのアドレスをByref引数で指定された変数に格納することに。
その他、LoadLibraryとGetProcAddressを行う関数と、GetExitCodeThreadのラップ関数を作った。


そんなわけで、以下のような感じで手軽に別スレッド実行を行えるようになったが、何に使うのかは不明。
時間のかかる関数を実行する間スクリプトの処理を止めたくない場合などに使うのだろうか。

s2=Title
s1=this is test message
pMB:=GetProc("user32.dll","MessageBoxA")
th:=SubThreadCall(GetProc("user32.dll","MessageBoxA"),pRetVal,0,&s1,&s2,2)
Loop{
if(GetExitCodeThread(th)!=259){
break
}
}
MsgBox,% gInt(pRetVal)

投稿ファイル名: MultiThread.zip
http://lukewarm.s101.xrea.com/bbs/file/1146398137_47.zip
サイズ: 1049 bytes
101KB
名前: E-mail:
ファイル:
0ch BBS 2005-10-08