タイトル | : Re^2: メモリマップドファイルのデータ渡し不具合 |
記事No | : 11585 |
投稿日 | : 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
|