忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

共有メモリとしてのメモリマップドファイルの使い方(MemoryMappedFile,CreateOrOpen,CreateViewAccessor)

プロセス間での通信を簡単に行いたい場合には、メモリマップドファイルが使えます。 メモリマップドファイルはその名の通り、プログラム上のメモリ空間にファイルを読込んで、連続したメモリ空間として取り扱えます。 そのメモリ空間を読み書きすることで、プロセス間の通信ができます。

今回は、実際のデータファイルを指定しない方法での、メモリマップドファイルの使い方を示します。

以下のソースにその関数を記します。
このフォームは、ボタンを2個と、テキストボックスを1個配置します。 Button1 はテキストボックスの文字列をメモリマップドファイルへの書込み処理を行い、 Button2 はメモリマップドファイルから読込みを行います。

MemoryMappedFile.CreateOrOpen はマップ名とメモリ領域のサイズを指定し、メモリマップドファイルのオープンを行います。 その後、MemoryMappedFile.CreateViewAccessor のアクセサを使って、メモリ空間への読み書きを行います。

共有メモリとしてのメモリマップドファイルの使い方

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Text

Public Class frmMemMap

    'テキストボックスの内容をメモリマップドファイルに書込む
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        'メモリ上にメモリマップドファイルをオープンする
        Dim mmf As MemoryMappedFile = MemoryMappedFile.CreateOrOpen("MemMapFileTest", 1024)
        'メモリマップドファイルのビューに対応するアクセサ生成
        Dim acc As MemoryMappedViewAccessor = mmf.CreateViewAccessor()

        'ASCII文字列をバイト配列に展開する
        Dim asciiBytes As Byte() = Encoding.ASCII.GetBytes(Me.TextBox1.Text.Trim)
        'バイト配列の最後尾にNULL(0x00)設定
        ReDim Preserve asciiBytes(UBound(asciiBytes) + 1)
        asciiBytes(UBound(asciiBytes)) = 0
        'アクセサを使ってメモリマップドファイルへの書込み
        acc.WriteArray(0, asciiBytes, 0, asciiBytes.Length)
    End Sub

    'メモリマップドファイルの内容を読込んで表示する
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        'メモリ上にメモリマップドファイルをオープンする
        Dim mmf As MemoryMappedFile = MemoryMappedFile.CreateOrOpen("MemMapFileTest", 1024)
        'メモリマップドファイルのビューに対応するアクセサ生成
        Dim acc As MemoryMappedViewAccessor = mmf.CreateViewAccessor()

        Dim byteVal As Byte
        Dim index As Integer = 0
        Dim sb As StringBuilder = New StringBuilder()
        Do
            'アクセサを使ってメモリマップドファイルから位置指定での読込
            byteVal = acc.ReadByte(index)
            If (byteVal = 0) Then
                'NULLの時点で終了
                Exit Do
            End If
            'バイト値を文字に変換
            Dim ascChar As Char = ChrW(byteVal)
            '文字列に加算
            sb.Append(ascChar, 1)
            'メモリマップドファイルの位置を進める
            index += 1
        Loop
        MsgBox("Read Text:" & sb.ToString)
    End Sub

End Class

このソースでは少し問題が有ります。テキストとしてASCII文字列しか扱えないので、 全角文字をテキストボックスに入れた場合には、期待した結果が得られません。
この件に関しては、後日解決したいと思います。



本日時間が在ったので Shift-JIS が扱える様に変更してみました。
メモリマップドファイルに書込むところで、文字列をバイト配列に展開する処理で、 エンコーディングを Shift-JIS として取得し、バイト配列に展開する様にします。

また、メモリマップドファイルから読込むところでは、バイト配列に取得した後で、 上記同様にエンコーディングを Shift-JIS としてバイト配列から文字列への変換を行います。
以下にそのソースを示します。

共有メモリとしてのメモリマップドファイルの使い方

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Text

Public Class frmMemMap

    'テキストボックスの内容をメモリマップドファイルに書込む
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        'メモリ上にメモリマップドファイルをオープンする
        Dim mmf As MemoryMappedFile = MemoryMappedFile.CreateOrOpen("MemMapFileTest", 1024)
        'メモリマップドファイルのビューに対応するアクセサ生成
        Dim acc As MemoryMappedViewAccessor = mmf.CreateViewAccessor()

        'Shift-JIS文字列をバイト配列に展開する
        Dim asciiBytes As Byte() = Encoding.GetEncoding("shift-jis").GetBytes(Me.TextBox1.Text.Trim)
        'バイト配列の最後尾にNULL(0x00)設定
        ReDim Preserve asciiBytes(UBound(asciiBytes) + 1)
        asciiBytes(UBound(asciiBytes)) = 0
        'アクセサを使ってメモリマップドファイルへの書込み
        acc.WriteArray(0, asciiBytes, 0, asciiBytes.Length)
    End Sub

    'メモリマップドファイルの内容を読込んで表示する
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        'メモリ上にメモリマップドファイルをオープンする
        Dim mmf As MemoryMappedFile = MemoryMappedFile.CreateOrOpen("MemMapFileTest", 1024)
        'メモリマップドファイルのビューに対応するアクセサ生成
        Dim acc As MemoryMappedViewAccessor = mmf.CreateViewAccessor()

        Dim byteVal As Byte
        Dim index As Integer = 0
        Dim arrBytes(0) As Byte
        Do
            'アクセサを使ってメモリマップドファイルから位置指定での読込
            byteVal = acc.ReadByte(index)
            If (byteVal = 0) Then
                'NULLの時点で終了
                Exit Do
            End If
            '配列に退避
            ReDim Preserve arrBytes(index)
            arrBytes(index) = byteVal
            'メモリマップドファイルの位置を進める
            index += 1
        Loop
        'バイト型配列を文字列に変換する
        Dim strData As String = Encoding.GetEncoding("shift-jis").GetString(arrBytes)
        MsgBox("Read Text:" & strData)
    End Sub

End Class

関連する記事

共有メモリとしてのメモリマップドファイルの使い方2・構造体の書込と読込
共有メモリとしてのメモリマップドファイルの使い方3・配列を持つ構造体の書込と読込

おすすめ本

PR

コメント

コメントを書く