Click here to Skip to main content
15,916,293 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I have a problem that has stumped me involving memory mapping, and interchange between C++ (Visual Studio 2012 under Win7 32bit) and Python 2.7.

In my C++ code I have a large (2Mbyte) image that updates at about 25Hz. I share this with another C++ .exe happily, using non-persistent (only present in memory, never on a hard drive) via memory mapping as below:

The C++ code is (extract only)

C++
TCHAR szFrameName[]=TEXT("IoAAOLICameraCameraFrame");

and

C++
// create mapped shared memory for the exposed frame data
hFrameMapFile = CreateFileMapping(
      INVALID_HANDLE_VALUE, // use paging file
      NULL, // default security
      PAGE_READWRITE, // read/write access
      0, // maximum object size (high-order DWORD)
      nCameras*sizeof(IoAFrameBuffer), // maximum object size (low-order DWORD)
      szFrameName); // name of mapping object

if (hFrameMapFile == NULL)
{
   _tprintf(TEXT("Could not create framebuffer file mapping object (%d).\n"),
GetLastError());
   return;
}

pFrame = (IoAFrameBuffer*) MapViewOfFile(hFrameMapFile, // handle to map object
      FILE_MAP_ALL_ACCESS, // read/write permission
      0,
      0,
      nCameras*sizeof(IoAFrameBuffer) );

if (pFrame == NULL)
{
   _tprintf(TEXT("Could not map view of framebuffer file (%d).\n"), GetLastError() );
   CloseHandle(hFrameMapFile);
   return;
}

All works fine. The data are shared and the images come through just fine to second *.exe accessing thia same memory mapped "file" called IoAAOLICameraCameraFrame.

However for good reasons I want to pick up from the mapped memory under Python. So I have:
C++
import mmap
import os

file = os.open(unicode('IoAAOLICameraCameraFrame'),os.O_RDWR)
fpx = mmap.mmap (file.fileno(),0)

Doesn't matter whether I use the above with or without unicode in front of the map share name. Always returns:

OSError [Errno 2] No such file or directory.

SO: Problem seems to be the way the memory mapped file is named. It only exists in the copmuter memory (non-persistent mapped file), so path names such as C:\IoAAOLICameraCameraFrame will not work.

Where am I going so badly wrong? Is there any way to look at the names and characteristics of these mapped objects under Win7?
Posted
Updated 5-Dec-20 18:08pm
v2
Comments
KarstenK 28-Aug-14 4:14am    
Try with a "Global\" Prefix.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx

Try this:
Python
import mmap

fpx = mmap.mmap (-1,-1,'IoAAOLICameraCameraFrame')
 
Share this answer
 
Sadly this does not work. Using:
fpx = mmap.mmap(-1,-1, 'IoAAOLICameraCameraFrame')
is not allowed because the 2nd parameter gives the maximum length of the mapped file. Running it with
fpx = mmap.mmap(-1,100, 'IoAAOLICameraCameraFrame')
actually runs but if you
print fpx
you get: <mmap.mmap object="" at="" 0x04071260="">
then trying to read by using:
data = fpx.read(100)
gives 100 bytes of null data.
As far as I can work out what happens with this approach is that it doesn't in fact find a mapping with that tag and so it creates a new mapped entity. It does not find the mapped object that is being generated by my C++ file.

Any further help gratefully received!
 
Share this answer
 
Comments
Albert Holguin 5-Sep-14 13:52pm    
If you have a specific reply to a solution, use the "comment" section under that solution. Don't post follow-ups as solutions please. Keeping this relatively orderly will help others in the future that may have the same problem you have.
Uses Linux (not windows)
This works using memory mapped files. I do not claim high speed or efficiency in any way. These are just to show an example of it working.

$ python --version
     Python 3.7.9

     $ g++ --version
     g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

The C++ side only monitors the values it needs. The Python side only provides the values.

Note: the file name "pods.txt" must be the same in the C++ and python code.


#include <sys/mman.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    int main(void)
      {
      // assume file exists
      int fd = -1;
      if ((fd = open("pods.txt", O_RDWR, 0)) == -1)
         {
         printf("unable to open pods.txt\n");
         return 0;
         }
      // open the file in shared memory
      char* shared = (char*) mmap(NULL, 8, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    
      // periodically read the file contents
      while (true)
          {
          printf("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", shared[0], shared[1], shared[2], shared[3], shared[4], shared[5],           shared[6], shared[7]);
          sleep(1);
          }

       return 0;
       }


The python side:

import mmap
    import os
    import time
     
    fname = './pods.txt'
    if not os.path.isfile(fname):
        # create initial file
        with open(fname, "w+b") as fd:
             fd.write(b'\x01\x00\x00\x00\x00\x00\x00\x00')

    # at this point, file exists, so memory map it
    with open(fname, "r+b") as fd:
        mm = mmap.mmap(fd.fileno(), 8, access=mmap.ACCESS_WRITE, offset=0)
    
        # set one of the pods to true (== 0x01) all the rest to false
        posn = 0
        while True:
             print(f'writing posn:{posn}')

             # reset to the start of the file
             mm.seek(0)
     
             # write the true/false values, only one is true
             for count in range(8):
                 curr = b'\x01' if count == posn else b'\x00'
                 mm.write(curr)

             # admire the view
             time.sleep(2)

             # set up for the next position in the next loop
            posn = (posn + 1) % 8

        mm.close()
        fd.close()



To run it, in terminal #1:

a.out  # or whatever you called the C++ executable
     0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
     0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
     0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
     0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
     0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00
     0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00
     0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00
     0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00
     0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00


i.e. you should see the 0x01 move one step every couple of seconds because of the sleep(2) in the C++ code.


in terminal #2:

python my.py  # or whatever you called the python file
    writing posn:0
    writing posn:1
    writing posn:2


i.e. you should see the position change from 0 through 7 back to 0 again.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900