標準入出力

戻る

VBを用いてCGIを作るために最低限必要なのは「標準出力」である。逆に言えば、VB自体にこの機能が付いていないから苦労するのであって、ここさえクリアすれば後はどうって事はない。標準出力と標準入力はペアなので、ここでは双方を説明しておく。重要なのはまず標準出力だろう。これがなければプログラム処理結果を表示させることができない。文字列をテキストエリアに入れたり、アップロードファイルを指定させて、POSTさせるとなると「標準入力」も必要になってくるが、まあ、最初は別に使うことはないだろう。

標準入出力を行うためには、API関数を使わなければならない。ステップとしては、とても簡単で、まずAPIを使い標準入出力用のファイルハンドラを取得し、その後、ファイルハンドラを使い入出力を実行するだけだ。入出力においては、バッファ用の文字列変数を用いて、一気に読み書きしてしまえば良い。実際に、宣言部と実行部のプログラム例を示しておこう。


標準入出力用の宣言部


    Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
    Private Declare Function ReadFile Lib "kernel32" _
        (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
         lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
    Private Declare Function WriteFile Lib "kernel32" _
        (ByVal hFile As Long, ByVal lpBuffer As String, ByVal nNumberOfBytesToWrite As Long, _
         lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
    Const STDIN_HANDLE = -10&
    Const STDOUT_HANDLE = -11&

APIの宣言は3つあり、標準入出力ハンドラを取得する「GetStdHandle」と、読み取りを行う「ReadFile」と、書き込みを行う「WriteFile」である。定数は2つだが、これらは標準入出力ハンドラを取得するAPIに渡すためのものである。

宣言が出来ているとして、標準出力の実行部プログラムを例示する。ここでは、Bufferという文字変数に格納されている文字列を送り出すものとしている。この例示では、Bufferの中身は空なので、動くはずはない。実際のプログラミングにおいては、送り出す文字列を引数にしたファンクションかサブルーチンにすれば良いであろう。


標準出力


    Dim Std_Hdl As Long
    Dim Written_Bytes As Long
    Dim API_Result as Long
    Dim StdOut_Length As Long
    Dim Buffer As String
    
    StdOut_Length = LenB(StrConv(Buffer, vbFromUnicode)) + 2
    Std_Hdl = GetStdHandle(STDOUT_HANDLE)
    API_Result = WriteFile(Std_Hdl, Buffer, StdOut_Length, Written_Bytes, ByVal 0&)

変数名は変更しても構わない。処理終了後、APIの戻り値と、書き込み済のバイト数が確認できる。大抵は問題無く動くし、ここでエラーが生じたとして、恐らくはWWWサーバ側がエラー値を戻すことになるので、エラートラップは設置しなくても構わないと考えている。えらく簡単にできてしまうもんだ。

さて、ついでと言っては何だが、標準入力の実行部も例示しよう。環境変数から「Content-Length」の値を持ってきて、これが0でなければ標準入力がある、と認識して動くようにすれば良い。出力と同様、Bufferという文字変数に標準入力値を入れるようにする。例によって、プログラムの例示。


標準入力


    Dim Std_Hdl As Long
    Dim Read_Bytes As Long
    Dim API_Result as Long
    Dim StdIn_Length As Long
    Dim Buffer As String
    
    StdIn_Length = Environ("CONTENT_LENGTH")
    If StdIn_Length > 0 Then
        Buffer = Space(StdIn_Length)
        Std_Hdl = GetStdHandle(STDIN_HANDLE)
        API_Result = ReadFile(Std_Hdl, Buffer, StdIn_Length, Read_Bytes, ByVal 0&)
    Else
        Buffer = ""
    End If

とまあ、こんな感じになる。大雑把に言って、標準出力とほとんど同じ様なものである。

なお、ファイルのアップロードなどを行う場合は、バイナリ変数の配列を指定することも必要な場合がある。この場合は、上記の「Dim Buffer As String」の代りに「Dim Buffer() As Byte」と「Redim Buffer(StdIn_Length)」を用いてやり、「ReadFile」中の「Buffer」を「Buffer(0)」としてちょっと改造してやれば動く。もしくは、上記で取得した標準入力文字列をバイト変数の配列領域にコピーする方法もあるだろう(確かAPIで出来たはずだが..忘れた)。

標準出力する文字列の作り方(?)は別項目としてあるので参照して頂きたい。標準入力で得たデータの意味や、扱い方についても、別項目とする。