共有メモリについて教えてください。
VB.NETで作成した異なるアプリ間で100000の要素をもつ配列を含んだデータを
共有したいのですが、2箇所の問題が解決できません。
<コード(概略)>
' 構造体
'------------------------------
Public Structure FileMapDataType
Dim Data0 As Short
Dim Data1 As Integer
<VBFixedString(10), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=10)> _
Public Data2 As String
' 本来は、2次元配列で500×200のデータを持ちたいのですが。。。
<VBFixedArray(100000), MarshalAs(UnmanagedType.ByValArray, SizeConst:=100001)> _
Public Data3() As Integer
Dim Data4 As Short
Dim Data5 As Double
Dim Data6 As Integer
Dim Data7 As Integer
Public Sub Initialize()
ReDim Data3(100000)
End Sub
End Structure
Private Structure SECURITY_ATTRIBUTES
Dim nLength As Integer '' 構造体の大きさ
Dim lpSecurityDescriptor As Integer '' セキュリティ・ディスクリプタへのポインター
Dim bInheritHandle As Integer '' ハンドルの継承設定
End Structure
' API
'------------------------------
Private Declare Auto Function CreateFileMapping Lib "kernel32" Alias "CreateFileMapping" _
(ByVal hFile As Integer, ByRef lpFileMappigAttributes As SECURITY_ATTRIBUTES, _
ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, _
ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer
Private Declare Auto Function OpenFileMapping Lib "kernel32" Alias "OpenFileMappingA" _
(ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, _
ByVal lpName As String) As Integer
Private Declare Auto Function MapViewOfFile Lib "kernel32" _
(ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, _
ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, _
ByVal dwNumberOfBytesToMap As Integer) As Integer
Private Declare Auto Function UnmapViewOfFile Lib "kernel32" _
(ByRef lpBaseAddress As Integer) As Integer
Private Declare Auto Function FlushViewOfFile Lib "kernel32" _
(ByVal lpBaseAddress As Integer, ByVal dwNumberOfBytesToFlush As Integer) As Integer
Private Declare Auto Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal Destination As Integer, ByRef Source As FileMapDataType, ByVal Length As Integer)
Private Declare Auto Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByRef Destination As FileMapDataType, ByVal Source As Integer, ByVal Length As Integer)
Private Declare Auto Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal Destination As Integer, ByRef Source As FileMapDataType2, ByVal Length As Integer)
Private Declare Auto Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByRef Destination As FileMapDataType2, ByVal Source As Integer, ByVal Length As Integer)
Private Declare Auto Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
' ファイルマップの作成関数内容
'------------------------------
Dim SecurityAttribute As SECURITY_ATTRIBUTES
Dim Ret As Integer
Dim DummyBuffer As FileMapDataType
DummyBuffer.Initialize()
hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, "TestFileMap")
If (hFileMap = 0) Then '' 新規にファイルマップを生成する。
'' 構造体を初期化する。
SecurityAttribute.bInheritHandle = 0 '' ハンドルの継承しない。
SecurityAttribute.lpSecurityDescriptor = 0 '' セキュリティをセットしない。
SecurityAttribute.nLength = Len(SecurityAttribute) '' 構造体のサイズを設定
hFileMap = CreateFileMapping(&HFFFFFFFF, SecurityAttribute, _
PAGE_READWRITE, 0, Len(DummyBuffer), "TestFileMap")
If (hFileMap = 0) Then Exit Function '' ハンドルが取れなければ失敗
lpFileMap = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0)
If lpFileMap = 0 Then Exit Function
'''' 新規作成の場合はデータを初期化する。
CopyMemory(lpFileMap, DummyBuffer, Len(DummyBuffer))
Ret = FlushViewOfFile(lpFileMap, Len(DummyBuffer))
Console.WriteLine("Len:" & Len(DummyBuffer).ToString)
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
<ご質問1>
CopyMemoryを行った際、以下のエラーが発生します。
'System.Runtime.InteropServices.MarshalDirectiveException' の
ハンドルされていない例外が Project1.exe で発生しました。
追加情報 : 内部的な制限 : 構造体が複雑すぎるか、大きすぎます。
構造体内の配列を100000→16000ぐらいにするとエラーが発生しなくなります。
何かサイズの制限があるのでしょうか?
100000配列のデータを渡すことが出来るのであれば方法を教えてください。
<ご質問2>
配列のサイズを小さくして実行してみると、共有メモリは作成されているのですが、
再度、同じ関数を呼ぶと、OpenFileMappingで0が返ってきます。
また、LastDllErrorは2が返ってきます。
記述方法が間違っているのでしょうか?
既存のファイルマップのハンドルを取得する方法を教えてください。
ご教示よろしくお願いいたします。
分類:[.NET]