プラグインから任意のラベルにジャンプする †
今回はjumpプラグインを例にラベルジャンプの方法を説明していきます。
Borland Delphi 6 Personal
- スクリプトに
1
2
3
4
5
|
| jump *Label_1
stop
*Label_1
mes "Hello, world !"
return
|
と書けばLabel_1にジャンプをして処理を実行し、ジャンプ元に処理を返すプラグインを作ります。
- ラベルジャンプの方法を学ぶ。
+
| | jump.dpr
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| | library jump;
uses
hsp3plugin in '..\hsp3plugin.pas';
procedure func_jump;
var
lbptr: PWord; begin
lbptr := exinfo.HspFunc_prm_getlb; exinfo.HspFunc_call(lbptr); end;
function cmdfunc(cmd: Integer): Integer; cdecl;
begin
exinfo.HspFunc_prm_next;
case cmd of
$00:
func_jump; else
exinfo.HspFunc_puterror(HSPERR_UNSUPPORTED_FUNCTION); end;
Result := RUNMODE_RUN;
end;
procedure register_jump(info: PHSP3TYPEINFO); stdcall;
begin
hsp3sdk_init(info); info.cmdfunc := cmdfunc; end;
exports
register_jump;
begin
end.
|
|
+
| | jump.as(プラグイン定義ファイル)
|
1
2
|
| #regcmd "register_jump", "jump.hpi"
#cmd jump $00
|
|
+
| | jump.hsp(サンプル)
|
1
2
3
4
5
6
7
8
9
|
| #include "jump.as"
mes "Hello world !"
jump *Label_1
mes "Good-bye !"
stop
*Label_1
mes "Jumpping !"
return 1
|
|
1
2
|
| lbptr := exinfo.HspFunc_prm_getlb; exinfo.HspFunc_call(lbptr);
|
スクリプトのラベルの位置はラベルへのポインタによって取得できます。
これを取得するのがHspFunc_prm_getlb関数です。
この関数で得られたラベルポインタを使って実際に処理をジャンプさせることができます。
gotoによるジャンプはHspFunc_setpcを、gosubによるジャンプはHspFunc_callを呼び出します。
HSPのreturnには通常のgosubによるパラメータ無しの復帰と、oncmdで見られるパラメータ付きの復帰があります。
HSPのヘルプによるとreturnで数値を返すと値によってシステム変数にリターンコードが格納されるようです。
これはプラグインからでも簡単に取得できますがreturnで値を返したのか返さなかったのかは、HSPCTX構造体のretval_levelメンバを調べることで分かります。
値を返さなかった時は0(FALSE?)、値を返した時は1(TRUE?)となります。
これを利用してjump()を以下のように書き換えることでリターンコード(整数)を正確に得ることができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
| uses
Windows, SysUtils, hsp3plugin in '..\hsp3plugin.pas';
var
ret: Array[0..255] of Char;
procedure func_jump;
var
lbptr: PWord;
begin
lbptr := exinfo.HspFunc_prm_getlb;
exinfo.HspFunc_call(lbptr);
if ctx.retval_level <> 0 then begin
StrFmt(ret, 'ret=%d', [ctx.stat]);
MessageBox(0, ret, 'returnコード', MB_OK);
end;
end;
|