0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

入出力ストリームをStreamRelay.NET.exe のプラグインとして実装する方法について説明する

Posted at

入出力ストリームをStreamRelay.NET.exe のプラグインとして実装する方法について説明する

StreamRelay.NET.exe/StreamRelay.NET.x86.exeには、いくつかの機能をプラグインとして実装できるようにインターフェイスを公開している。

今回は、標準入出力(オプションだと「-[Local|Remote]Port 0」の場合)のリダイレクト先のストリームをプラグインのインターフェイスとして公開していて、そのプラグインを作成する方法を記述する。


既存のプラグイン

ファイルから入力/出力とか、マイクから音声入力とか、スピーカーへ音声出力とか、音声認識とか、音声合成とか、名前付きパイプとか、指定されたURLへ送信とかそういうところに使われている。

プラグイン的には、このあたり。

  • Plugins\Win32\stdioFileC32.ddl
  • Plugins\Win64\stdioFileC64.ddl
  • Plugins\Win32\stdioSoundRecordMDX.ddl
  • Plugins\Win32\stdioSoundRecordSlimDX.x86.ddl
  • Plugins\Win64\stdioSoundRecordSlimDX.x64.ddl
  • Plugins\stdioFile.ddl
  • Plugins\stdioICMPTunnel.ddl
  • Plugins\stdioNamedPipe.ddl
  • Plugins\stdioSpeachRecognition.ddl
  • Plugins\stdioTCP.ddl
  • Plugins\stdioUrl.ddl
  • Plugins\stdioUrlWS.ddl

実装したプラグインの呼び出され方

-[Local|Remote]Port 0」が指定されて、ストリームの物理実体が標準入出力となっている状態で、プラグインで指定された引数が渡されると、標準入出力のリダイレクト先として、プラグインが呼ばれる。

という感じ。


実装するインターフェイス

以下のインターフェイスを継承したクラスを実装すればよい

  • IPlugin.dll 中の jp.dip.rocketeer.Plugins.IPluginStdioout インターフェイス

このクラス一つだけ実装すればよい。


jp.dip.rocketeer.Plugins.IPluginStdioout インターフェイス

StreamRelay.NET.exeが、引数/オプションの解析処理中に呼び出して、引数の指定内容によって有効化していれば、
標準入力を置き換える(リダイレクト)する場合は、プロパティ「CanInputStream=true」とする。
標準出力を置き換える(リダイレクト)する場合は、プロパティ「CanOutputStream=true」とする。

そうすると、StreamRelay.NET.exeで、(標準入出力の代わりに)ストリームを開く際に、入力を置き換えた(リダイレクト)場合にはgetInputStream()、出力を置き換えた(リダイレクト)場合には**getOutputStream()**が呼ばれる。

という感じ。

具体的には、起動直後の引数/オプションの解析処理中に、
int Args(String iStr1, String iStr2, String iStr3);
を呼び出すので、自分の引数であれば、プロパティ「CanInputStream=true」または「CanOutputStream=true」にして、使った引数の数を返してくれればよい。
自分の引数でなければ、0を返す。

より、具体的には、
例えば、
c:\>StreamRelay.NET.exe a b c d e f
というコマンドラインで起動したら、

  1. iStr1=a, iStr2=b, iStr3=c, で、Args() を呼び出し、
  2. iStr1=b, iStr2=c, iStr3=d, で、Args() を呼び出し、
  3. iStr1=c, iStr2=d, iStr3=e, で、Args() を呼び出し、
  4. iStr1=d, iStr2=e, iStr3=f, で、Args() を呼び出し、
  5. iStr1=e, iStr2=f, iStr3=NULL, で、Args() を呼び出し、

という感じ・・・

例えば、iStr1=b, iStr2=c, iStr3=d, の時、自分の引数ということで、iStr1=b, iStr2=c, を Args() で使用したら、2を返す。すると次は iStr1=d, iStr2=e, iStr3=f, で、Args() が呼び出される。

ということになっている。


Args()の呼ばれ方の留意点

Args()の第一引数の先頭が「-Local」または「-Remote」の場合だけ、Args()は呼び出される。

しかも、先頭の「-Local」または「-Remote」は削られた形で呼び出されるので注意。

より、具体的には、
例えば、
c:\>StreamRelay.NET.exe -LocalStdinRedirect b c d e f
というコマンドラインで起動したら、

1番最初だけ、「StdinRedirect」というように「-Local」または「-Remote」が削られて、結局「StdinRedirect」「b」「c」という引数でArgs()が呼ばれる。

ということになる。


jp.dip.rocketeer.Plugins.IPluginStdioout インターフェイスで定義しているメソッド/プロパティ

実装する必要があるのは以下

jp.dip.rocketeer.Plugins.IPluginStdiooutインターフェイスで定義されているのは、以下のとおり

String[] usage { get; }
ヘルプに引数を表示する
int Args(String iStr1, String iStr2, String iStr3)
引数を解析して、自分のものだったかどうかを返す(「名前」「 値」の二つを必要とするバージョン)
第一引数の「-Local」または「-Remote」は削られて渡される
String InputStreamName { get; }
現在の状態を表示する(設定を受け取っての状態(Verboseモード時や接続状態の表示時に呼び出される))(入力側)
String OutputStreamName { get; }
現在の状態を表示する(設定を受け取っての状態(Verboseモード時や接続状態の表示時に呼び出される))(出力側)
Stream getInputStream()
ストリームを取得する(入力)
サーバ系統の場合(ローカル側で IsServer=True)は、接続ごとにこのメソッドが呼び出されるようなイメージ
よって、呼び出しごとに新規ストリームを返すというようなイメージ
Stream getOutputStream()
ストリームを取得する(出力)
サーバ系統の場合(ローカル側で IsServer=True)は、接続ごとにこのメソッドが呼び出されるようなイメージ
よって、呼び出しごとに新規ストリームを返すというようなイメージ
Boolean CanInputStream { get; }
InputStream が利用可能かどうかを示す
Boolean CanOutputStream { get; }
OutputStream が利用可能かどうかを示す
Boolean IsLocal { get; set; }
ローカルか、リモートか (StreamRelay.NET.exeがセットする)
UInt32 SleepTime { get; set; }
スレッドのインターバル(ms) (StreamRelay.NET.exeがセットする)
UInt32 RecvBufSize { get; set; }
バッファサイズ (StreamRelay.NET.exeがセットする)
Encoding InputEncoding { get; set; }
文字コード(必要な場合) (StreamRelay.NET.exeがセットする)
Encoding OutputEncoding { get; set; }
文字コード(必要な場合) (StreamRelay.NET.exeがセットする)
Boolean IsSameStream { get; set; }
ストリームは入力だけ、出力だけではなくて、入出力の時、True。
True の場合、output 系統のインスタンス側のメソッドは呼び出されない。
Boolean IsServer { get; set; }
サーバ(複数クライアントの多重接続)として動作させるかどうか
Stop()
サービスとして動作しているような場合の終了処理を記述する
例: ローカルで、TCPサーバとして起動している場合のサーバの停止処理
接続中のストリームの停止処理は、別途しているので、待ち受けサーバの停止処理だけ記述すればよい
void init(PluginManagePublicObj iObj)
他のプラグイン(乱数とか文字コードとか)も操作できるオブジェクトを渡す (引数はStreamRelay.NET.exeがセットして呼び出される)

jp.dip.rocketeer.Plugins.IPluginBaseインターフェイスで定義されている分については、インターフェイス IPluginBase についてを参照


目次へ戻る

目次というか最初の一歩

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?