none
Memory Mapped File Help

    Question

  • Hi,
    I need to set IPC between two processes. I am trying to create a shared memory to
    write data and make it available to another application.
    I am using VS2005,  I created the project as Visual Basic Console Application.

    The problem is that I just can´t create the shared memory.   "hFileMap" in the following line keeps on
    throwing "0":

    hFileMap = CreateFileMapping(MMF_IN_SYSTEM_PAGE_FILE, NULL, PAGE_READWRITE, 0, 0, "MySharedMapping")

    thus, the pointer "lPointer" is 0 as well, which means that no memory was allocated.:

    lPointer = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0)

    I´ve spent quite a lot of time searching the internet without success. All I´ve found is VB6 related.
     Nevertheless I guess the problem could be in the parameters of CreateFileMapping function.  I am not
    quite sure if they should be ByVal or ByRef, but more important: i have found that some people (even
    the snippet from VB6 API Viewer) declares:

    lpFileMappingAttributes As SECURITY_ATTRIBUTES

    wich, honestly I have no idea how to deal with.  I know it is a structure, but which values should it have?...

    Can anybody help?  is there any detail I am missing? any idea?
    I don´t get any runtime error.

    Thanks,
    Josue




    Code Snippet

    Module Module2

        Private Const NULL = 0
        Private Const MMF_IN_SYSTEM_PAGE_FILE = &HFFFFFFFF  ' -1

        'MISC CONSTs
        Private Const VT_BY_REF = &H4000&
        Private Const FILE_SHARE_READ = &H1
        Private Const FILE_SHARE_WRITE = &H2
        Private Const MOVEFILE_REPLACE_EXISTING = &H1
        Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
        Private Const FILE_ATTRIBUTE_NORMAL = &H80
        Private Const FILE_BEGIN = 0
        Private Const CREATE_NEW = 1
        Private Const OPEN_EXISTING = 3
        Private Const OPEN_ALWAYS = 4
        Private Const GENERIC_READ = &H80000000
        Private Const GENERIC_WRITE = &H40000000
        Private Const PAGE_READWRITE = 4
        Private Const FILE_MAP_WRITE = &H2
        Private Const FILE_MAP_READ = &H4
        Private Const FADF_FIXEDSIZE = &H10

        Dim hFile, hFileMap, lPointer As Integer

      
        Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Integer, _
        ByVal lpFileMappingAttributes As Integer, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, _
        ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer

        Declare Function MapViewOfFile Lib "kernel32" (ByRef hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, _
        ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As Integer

      
        Private Declare Function UnmapViewOfFile Lib "kernel32.dll" (ByVal lpBaseAddress As Integer) As Boolean
        '##########################################################################################################
      
      
        Sub Main()
           test2()
        End Sub


        Public Sub test()
            Console.WriteLine("Creating Shared Memory")
            hFileMap = CreateFileMapping(MMF_IN_SYSTEM_PAGE_FILE, NULL, PAGE_READWRITE, 0, 0, "MySharedMapping")
            If hFileMap = 0 Then
                Console.WriteLine("Creating of Shared Memory Failed")
            End If
            lPointer = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0)
        End Sub


     

    End Module

    Thursday, August 09, 2007 4:03 PM

Answers

  • There's a codeproject c# sample that might be of more use than a vb6 example. C# is very similar to vb.net.

     

    First use Option Strict and Option Explicit to remind yourself to state the types when you declare variables.

    Your constants are untyped, and so they are created as Object.

     

    If you look in the msdn library then you'll find the C declaration:

     

    HANDLE CreateFileMapping(
      HANDLE hFile,
      LPSECURITY_ATTRIBUTES lpAttributes,
      DWORD flProtect,
      DWORD dwMaximumSizeHigh,
      DWORD dwMaximumSizeLow,
      LPCTSTR lpName
    );

     

    So hFile is a handle, the msdn says to use IntPtr for handles.

    lpAttributes is a pointer to a structure, but the documentation says to set it to null, so it is unrequired. We'll declare it properly though. See msdn: default marshaling for value types.

    DWORDS are unsigned integers, it says so in the library. So use UInteger.

     

    I get...

     

    Code Snippet
    Option Strict On
    Option
    Explicit On

    Imports
    System.Runtime.InteropServices
    Imports System.ComponentModel

    Public Class Form1

        
    Private INVALID_HANDLE_VALUE As New IntPtr(-1)
        
    Private Const PAGE_READONLY As UInteger = 2
        
    Private Const PAGE_READWRITE As UInteger = 4
        
    Private Const FILE_MAP_WRITE As UInteger = 2
        
    Private Const FILE_MAP_READ As UInteger = 4

        
    Private hFile, hFileMap, lPointer As IntPtr

        <DllImport(
    "kernel32")> _
        
    Private Shared Function CreateFileMapping(ByVal hFile As IntPtr, _
        
    ByRef lpFileMappingAttributes As IntPtr, ByVal flProtect As UInteger, ByVal dwMaximumSizeHigh As UInteger, _
        
    ByVal dwMaximumSizeLow As UInteger, ByVal lpName As String) As IntPtr
        
    End Function

        <DllImport("kernel32")> _
        
    Private Shared Function MapViewOfFile(ByVal hFileMappingObject As IntPtr, ByVal dwDesiredAccess As UInteger, _
        
    ByVal dwFileOffsetHigh As UInteger, ByVal dwFileOffsetLow As UInteger, ByVal dwNumberOfBytesToMap As UInteger) As IntPtr
        
    End Function

        Private Declare Function UnmapViewOfFile Lib "kernel32.dll" (ByVal lpBaseAddress As IntPtr) As Boolean

        Sub New()
            InitializeComponent()
            test2()
        
    End Sub

        Public Sub test2()
            Console.WriteLine(
    "Creating Shared Memory")
            
    ' Ask for 1024 bytes.
            hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, Nothing, PAGE_READWRITE, 0, 1024, "MySharedMapping")
            
    If hFileMap.Equals(IntPtr.Zero) Then
                Throw New Win32Exception
            
    End If
            lPointer = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0)
            
    If lPointer.Equals(IntPtr.Zero) Then
                Throw New Win32Exception
            
    End If
            If UnmapViewOfFile(lPointer) = False Then
                Throw New Win32Exception
            
    End If
        End Sub
    End
    Class

     

    Friday, August 10, 2007 1:47 AM

All replies

  • There's a codeproject c# sample that might be of more use than a vb6 example. C# is very similar to vb.net.

     

    First use Option Strict and Option Explicit to remind yourself to state the types when you declare variables.

    Your constants are untyped, and so they are created as Object.

     

    If you look in the msdn library then you'll find the C declaration:

     

    HANDLE CreateFileMapping(
      HANDLE hFile,
      LPSECURITY_ATTRIBUTES lpAttributes,
      DWORD flProtect,
      DWORD dwMaximumSizeHigh,
      DWORD dwMaximumSizeLow,
      LPCTSTR lpName
    );

     

    So hFile is a handle, the msdn says to use IntPtr for handles.

    lpAttributes is a pointer to a structure, but the documentation says to set it to null, so it is unrequired. We'll declare it properly though. See msdn: default marshaling for value types.

    DWORDS are unsigned integers, it says so in the library. So use UInteger.

     

    I get...

     

    Code Snippet
    Option Strict On
    Option
    Explicit On

    Imports
    System.Runtime.InteropServices
    Imports System.ComponentModel

    Public Class Form1

        
    Private INVALID_HANDLE_VALUE As New IntPtr(-1)
        
    Private Const PAGE_READONLY As UInteger = 2
        
    Private Const PAGE_READWRITE As UInteger = 4
        
    Private Const FILE_MAP_WRITE As UInteger = 2
        
    Private Const FILE_MAP_READ As UInteger = 4

        
    Private hFile, hFileMap, lPointer As IntPtr

        <DllImport(
    "kernel32")> _
        
    Private Shared Function CreateFileMapping(ByVal hFile As IntPtr, _
        
    ByRef lpFileMappingAttributes As IntPtr, ByVal flProtect As UInteger, ByVal dwMaximumSizeHigh As UInteger, _
        
    ByVal dwMaximumSizeLow As UInteger, ByVal lpName As String) As IntPtr
        
    End Function

        <DllImport("kernel32")> _
        
    Private Shared Function MapViewOfFile(ByVal hFileMappingObject As IntPtr, ByVal dwDesiredAccess As UInteger, _
        
    ByVal dwFileOffsetHigh As UInteger, ByVal dwFileOffsetLow As UInteger, ByVal dwNumberOfBytesToMap As UInteger) As IntPtr
        
    End Function

        Private Declare Function UnmapViewOfFile Lib "kernel32.dll" (ByVal lpBaseAddress As IntPtr) As Boolean

        Sub New()
            InitializeComponent()
            test2()
        
    End Sub

        Public Sub test2()
            Console.WriteLine(
    "Creating Shared Memory")
            
    ' Ask for 1024 bytes.
            hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, Nothing, PAGE_READWRITE, 0, 1024, "MySharedMapping")
            
    If hFileMap.Equals(IntPtr.Zero) Then
                Throw New Win32Exception
            
    End If
            lPointer = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0)
            
    If lPointer.Equals(IntPtr.Zero) Then
                Throw New Win32Exception
            
    End If
            If UnmapViewOfFile(lPointer) = False Then
                Throw New Win32Exception
            
    End If
        End Sub
    End
    Class

     

    Friday, August 10, 2007 1:47 AM
  • Hi,

    thanks, that worked for me.  Though I reviewed some docs I was not quite sure if I was declaring
    correcly the functions.  The constants were not a problem, they worked fine, but I will follow your advise of
    declaring the type.

    Now I am on the right track... thanks again,

    Josue
    Monday, August 13, 2007 7:44 AM