SHIORI Binary Extender Standard/0.0
(Working Draft/20020128-02)

SHIORI Binary Extender(SBE)とは?

栞に対するバイナリ拡張の形式を標準化することで、機能拡張に対する栞開発者の負荷を軽減すると同時に、ゴーストデベロッパが、使用している栞に要求する機能が無いことを理由に、思いついたネタを諦めたり、もしくはそのためだけに栞を乗り換える必要をなくすためのものです。
関連スレッド:栞を考えるスレ(現在、議論中)

履歴

2002-01-28-02
名称案。
返り値。
関数の形式。
ファイル配置。
2002-01-28-01
公開。

補足

この文書中で用いられているSHIORI Binary ExtenderもしくはSBEという呼称は文書製作者が独断で用いているものであって決定事項ではありません。 また内容自体が議論の叩き台です。

名称

なにはともあれ。ある程度短いほうが会話時なんかに便利かも。

栞一心
Shioret
栞プラグイン
何か。用プラグインと混同?
ちょっと長い。
みりす。
SBE
名が体を表していない上にやたら固っくるしい。

SBEの実装

DLL形式のSBE

Windows上においては、SBEは原則的にDLLによって実装される。(EXE形式による実装に関しては後述)。

実行関数の方式

案1
HGLOBAL execute(HGLOBAL h, long *len);
GlobalAllocで確保されたメモリ領域に単一の文字列として引数その他の情報をセットして渡し、結果は、SBE側でGlobalAllocされた領域に単一の文字列としてセットされ、そのハンドルが返り値になる。同時に引数で渡されたlong*の指す領域に文字列の長さをセットする必要がある。
問題点
文字列から引数をとりだすためのパーザが必要になる。栞・真琴・プラグイン等の開発経験者にとっては問題ないが、一からはじめようとする人間にはつらいかもしれない。
案2
HGLOBAL execute(HGLOBAL h);
案1の変形で、文字列をかならず0x00で終端することで文字列長の指定を不要にする。 メモリ領域に対する取り扱いは案1に準じる。
問題点
ほぼ1と変わらないが、加えて0x00を探す処理が必要なため多少とはいえ遅くなる、引数中に0x00を含めることができない。
案3
HGLOBAL execute(int argc, char* argv[]);
C/C++のmain()風。argcが引数の数を指し、argvにはchar*の配列に格納された引数本体がセットされる。返り値は0x00で終端された文字列が格納されたHGLOBAL。
問題点
結局のところ返り値側は書式化された文字列を返すか、もしくは単一のデータしか渡せないので中途半端。加えて、案2で挙げたの問題点とほぼ共通の問題がある。
案4
HGLOBAL execute(int* retlen, int argc, char* argv[], int[] argn);
案3に文字列の長さを加えたもの。
問題点
中途半端に冗長。案2で挙げたような問題点は解決されるが、果たしてそれに見合うコストなのか。
案5
int execute(HGLOBAL argc, HGLOBAL args, HGLOBAL argn);
//int execute(int* argc, char* args[], int argn[])
それ自体がGlobalAllocされたargc, args, argnにそれぞれ引数の数、引数の配列、引数の文字列長をセットして渡し、返り値も同じargc, args, argnにセットして返す。返り値に返り値の数をセットすればint* argcではなくint argcにできるが。
問題点
簡便に書けることが利点であるはずの案3を元にしていることを考えれば論外だろう。
案6
HGLOBAL execute(HGLOBAL args);
引数にはNULL終端されたchar*ポインタの配列が渡される。返り値はポインタに同じ形式で文字列を格納して返す。
問題点
冗談。たしかに引数は少ないがそれだけ。
総括
既に何か。本体が使用している案1を除くとDelphiとの親和性が不明。現実的にはWindows上のDLL開発に用いられるのはC/C++かDelphiが圧倒的だろうが、なるべく汎用性があったほうがいいだろう。
関数の形式
__cdeclか__stdcallか。
何か。用各種DLLの仕様に沿うなら__cdecl。

文字列引数の形式

引数、返り値を単一の文字列として渡す場合の形式。
案1
COMMAND subcommand version[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
[CRLF]

version statusnumber statusstring[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
[CRLF]
各行はCRLFで区切られ、一行目のみ半角スペースで区切られ、2行目以降は": "で区切られたKey,valueの対。
SHIORI/2.x、SSTP等で使われている形式。(pluginの場合subcomman部分が無い点が異なる)。それらに触れたことのある人間にとっては既存のソースを流用できる。
案2
COMMAND[0x01]subcommand[0x01]version[0x02]
Name[0x01]Value[0x02]
Name[0x01]Value[[0x02]
Name[0x01]Value[0x02]
[0x02]

version[0x01]statusnumber[0x01]statusstring[0x02]
Name[0x01]Value[0x02]
Name[0x01]Value[0x02]
Name[0x01]Value[0x02]
[0x02]
形式は案1に準じるが区切りとして0x01、0x02といった値を用いる。特にvalueの内容などと衝突する可能性が低くなるが、純粋な文字列とは言い難く、人によっては抵抗を感じる。
案3
Command: command[CRLF]
SubCommand: subcommand[CRLF]
Version: version[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
[CRLF]

Version: version[CRLF]
Status: number[CRLF]
Name: Value[CRLF]
Name: Value[CRLF]
[CRLF]
全体をkey: value[CRLF]形式に統一したもの。パーザの処理が統一されるという利点はあるが、一行目の時点では対応した形式であるという判断ができないのが欠点。
案4
Command: GET Version SHIORIPLUGIN/1.0[CRLF]
案1と案3の混合だが余計ややこしいだけだと思われる。

複数引数の並び

main()系の引数形式の場合の並び順。コマンドライン引数のように"-l"のような文字列を使って意味を識別するのは多分に冗長なので、できれば順番のみで識別できるようにしたい。

SBEの寿命

案1
SBEのDLLは原則として栞のload時に読み込まれ、栞のunload時に破棄される。
案2
必要時にのみ読み込まれ、処理終了後破棄される。
総括
案1の場合、多数のSBEを使用した場合メモリを大量に要求し、 案2の場合、長期的な状態を保持することが困難である。
折衷案として、長期的な状態を保持することが必要なSBEは案1、そうでないものは案2を取るのが現実的かもしれない。
また、保存したいデータを返り値に含めて渡し、呼び出し側の栞等で保存するという手法はどうだろう?(これはEXE形式のSBEでも用いることができるかもしれない。)

返り値

SBEから栞に返される値の定義。形式自体は引数の形式に大きく依存することになるだろう。
形式
栞のようにステータスコードを返すか?
返す場合、どういった意味のものを用意するか。
また、Key: value形式の場合、どういったKey名を使用するか。
複数返り値のサポート
複数返り値のサポートを仕様に含めるか?
とりあえず仕様で規定しておくにこしたことはない。
栞側が複数の返り値に対応しない場合(栞の固有スクリプトにおいて配列変数等が使用できない)場合の扱い。
1.栞側がどちらを要求しているかをSBE側に伝え、それによって単数/複数を切り替える
2.常に単数/複数の双方を返す。

非同期SBE

非同期SBEに必要な仕様。

EXE形式による実装

EXE形式でSBEを実装する場合、Proxy DLLを経由する。 Proxy DLLはEXEによるSBEを実行し、その結果を返す。結果はDLLを経由して栞に渡される。引数と標準出力のみを扱えばいいので敷居が低いと思われる。と同時に、外部プロセスとして実行されるため、こみいった処理や非同期的な処理に適しているかもしれない。

SBEの定義ファイル。

SBEを呼び出す栞に情報を渡すために、一定の書式のテキストファイルが用意される。
形式については議論待ち。

SBEのファイル配置

議論待ち。

余談

各栞の固有スクリプトから呼び出されるのではなく、一定の条件下(Event, Reference[n]の内容等)で処理を全面的に代行する形式のバイナリ拡張フレームワークに関しても妄想中。もしくはキメラ栞(イベント処理は里々に任せて、AIトーク部分だけを別の栞で記述するとか)

誰もが最小限の労力で最大限の結果を得られるための手段として。
SDN(sdn@boreas.dti.ne.jp