tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^2: メモリマップドファイルのデータ渡し不具合
投稿日: 2008/02/29(Fri) 19:26
投稿者ダリア
リルさま、お返事ありがとうございます。
どこまでプログラムソースを出すべきか、よく分からず追加情報が遅れましたことお詫びいたします。
現状とプログラムは、このような感じです。
また、色々試した結果も加えてみました。状況は変わらずですが、少し分かったところもあります。

構造体の入れ子構造に問題があるのかと思い、以下のように変更してみました。
Public Type DataType
    state As Integer        '構造体の書き込み条件
    change As Integer      'ステーション切り替え
    EventCode As Integer        'イベントコード

    D0_Log(45) As String * 100 'ログデータ(100文字X45行)
    D0_Dummy As String * 512   'ログデータ(サイズ)
    D0_A(16) As Integer         'Aデータ
    D0_B(16) As Integer      'Bデータ
    
    D1_Log(45) As String * 100 'ログデータ(100文字X45行)
    D1_Dummy As String * 512   'ログデータ(サイズ)
    D1_A(16) As Integer         'Aデータ
    D1_B(16) As Integer      'Bデータ
    
End Type
これで実行しても、状況は変わりませんでした。

次に、プログラムの簡易版を作成しました。
A側でメモリマップドファイルの開始と初期化、change切り替え、表示。
B側でメモリマップドファイルの開始、データの書き込みと表示を行います。

change切り替え時に問題が発生しているかを確認しました。
(本来、change=1でB側がD0へデータを入れる。change=2でB側がD1へデータを入れるのですが。)
change=1の時にデータをD0,D1ともに入れる。B側はD0,D1とも表示するが、A側はD0しか表示しない。
change=2の時にデータをD0,D1ともに入れる。B側はD0,D1とも表示するが、A側はD0しか表示しない。
以上により、change切り替えの処理に(多分)問題がないことが分かりました。


ふと思いついて、以下のように構造体のD0とD1をひっくり返してみました。

Public Type DataType
    state As Integer        '構造体の書き込み条件
    change As Integer      'ステーション切り替え
    EventCode As Integer        'イベントコード

    D1_Log(45) As String * 100 'ログデータ(100文字X45行)
    D1_Dummy As String * 512   'ログデータ(サイズ)
    D1_A(16) As Integer         'Aデータ
    D1_B(16) As Integer      'Bデータ

    D0_Log(45) As String * 100 'ログデータ(100文字X45行)
    D0_Dummy As String * 512   'ログデータ(サイズ)
    D0_A(16) As Integer         'Aデータ
    D0_B(16) As Integer      'Bデータ
    
    
End Type

すると、A側はD1しか表示しなくなったのです。つまり、A側は上半分しか認識していないようです。
構造体の指定の仕方が間違っているのかも?という感じになってきました。
問題は、A側、B側のプログラムというよりは、API関連か、もしくは構造体指定部分のようです。
(プログラムはA側、B側。共通で(おのおの同じ)API関連と構造体指定部を別モジュールで作成しています。A側、B側でのメモリマップドファイルの処理は関数渡しとして別モジュールに渡しています)
これから、A側とB側でサイズが異なっているのでは?という疑いが発生します。
そこで、構造体のサイズを”ファイルマップの参照”Len(lpData)で確認しました。
    A側 10370
    B側 10370
よって、指定しているデータサイズは(多分)問題ないことが分かります。

これらの結果、マッピングして欲しいデータのエリアが異なっているように思います。
マッピング位置がずれているとみるべきなのでしょうか?

API関連の関数は別モジュールに以下のようにプログラムしています。(一部抜粋)
(これは、A,Bともに共通です)

Private DummyData As DataType

' 機能      : ファイルマップの作成(Data)
Public Function MakeFileMapD(ByVal strfilemapname As String, _
                            ByRef hFileMap As Long, _
                            ByRef lpfilemap As Long) As Boolean
                            
    Dim SecurityAttribute As SECURITY_ATTRIBUTES
    Dim Ret As Long
    
    MakeFileMapD = False '' データの初期化
    
    '' ファイルマップがすでに作成されていれば、OpenFileMapping()
    '' 無ければ、CreateFileMapping()
    hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strfilemapname)
    If (hFileMap = 0) Then '' 新規にファイルマップを生成する。
        '' 構造体を初期化する。
        SecurityAttribute.bInheritHandle = 0&           '' ハンドルの継承しない。
        SecurityAttribute.lpSecurityDescriptor = 0& '' セキュリティをセットしない。
        SecurityAttribute.nLength = 34  '' 構造体のサイズを設定
        
        hFileMap = CreateFileMapping(-1&, _
                                     SecurityAttribute, _
                                     PAGE_READWRITE, _
                                     0&, _
                                     Len(DummyData), _
                                     strfilemapname)
        If (hFileMap = 0) Then Exit Function    '' ハンドルが取れなければ失敗
        
        lpfilemap = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0&, 0&, 0&)
        If lpfilemap = 0 Then Exit Function
        
        '' 新規作成の場合はデータを初期化する。
        CopyMemory ByVal lpfilemap, ByVal DummyData, ByVal Len(DummyData)
        Ret = FlushViewOfFile(ByVal lpfilemap, Len(DummyData))
        If Ret = 0 Then Exit Function
    Else
        lpfilemap = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0&, 0&, 0&)
        If lpfilemap = 0 Then Exit Function
    End If
    MakeFileMapD = True
    
End Function


'データのクリア(Data)
Public Function ClearFileMapD(ByRef lpData As DataType, _
                               ByRef lpfilemap As Long) As Long
    Dim Ret As Long
    
    '' ファイルマップが準備できていない。
    If (lpfilemap = 0) Then ClearFileMapD = -1&

'データのクリア
    CopyMemory ByVal lpfilemap, ByVal DummyData, ByVal Len(DummyData)
    Ret = FlushViewOfFile(ByVal lpfilemap, Len(DummyData))
    If Ret = 0 Then Exit Function

End Function


' 機能      : ファイルマップの終了
Public Function CloseFileMap(ByRef hFileMap As Long, _
                             ByRef lpfilemap As Long) As Boolean
    CloseFileMap = False
    
    If hFileMap <> 0 Then
        If CloseHandle(hFileMap) Then hFileMap = 0&
    End If
    
    '' ポインタ渡しなので、ByVal となる。
    If UnmapViewOfFile(ByVal lpfilemap) Then
        lpfilemap = 0&
        CloseFileMap = True
    End If
    
End Function


' 機能      : ファイルマップの参照(Data)
Public Function GetFileMapDataD(ByRef lpData As DataType, _
                               ByRef lpfilemap As Long) As Long
    Dim Ret As Long
    Dim i As Long
    
    '' ファイルマップが準備できていない。
    If (lpfilemap = 0) Then GetFileMapDataD = -1&
    
    '' ファイルマップデータを取得
    CopyMemory ByVal lpData, ByVal (lpfilemap), ByVal Len(lpData)
    
    GetFileMapDataD = Len(lpData) '' 読み取ったデータバイト数
    
End Function


' 機能      : ファイルマップへデータを設定(Data)
Public Function SetFileMapDataD(ByRef lpData As DataType, _
                               ByRef lpfilemap As Long) As Boolean
    Dim Ret As Long
'    Dim BuffCount As Long   '' 記録するバッファの位置
    SetFileMapDataD = False
    
    '' ファイルマップが準備できていない。
    If (lpfilemap = 0) Then Exit Function
        
    '' ファイルマップデータを設定
    CopyMemory ByVal (lpfilemap), ByVal lpData, ByVal Len(lpData)
    Ret = FlushViewOfFile(ByVal lpfilemap, Len(lpData))
    If Ret <> 0 Then SetFileMapDataD = True
    
End Function

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。