Shared Memory Example (Python, ctypes, VC++)

  • Thread starter Srijit Kumar Bhadra
  • Start date
S

Srijit Kumar Bhadra

Hello,
Here are code snippets to create and access shared memory in Python
with and without ctypes module.

With regards,
Srijit

Filename : SharedMemCreate.py

import msvcrt, mmap
from ctypes import *

FILE_MAP_ALL_ACCESS = 0xF001F
INVALID_HANDLE_VALUE = 0xFFFFFFFF
SHMEMSIZE = 256
PAGE_READWRITE = 0x04
szName = c_char_p("MyFileMappingObject_ctypes")
szMsg = "Message from Python(ctypes) process"

hMapObject = windll.kernel32.CreateFileMappingA(INVALID_HANDLE_VALUE,
None, PAGE_READWRITE, 0, SHMEMSIZE, szName)
if (hMapObject == 0):
print "Could not open file mapping object"
raise WinError()

pBuf = windll.kernel32.MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS,
0, 0, SHMEMSIZE)
if (pBuf == 0):
print "Could not map view of file"
raise WinError()
else:
memcpy = cdll.msvcrt.memcpy
memcpy(pBuf, szMsg, len(szMsg))

shmem = mmap.mmap(0, 256, "MyFileMappingObject", mmap.ACCESS_WRITE)
shmem.write("Message from Python process")

msvcrt.getch()

windll.kernel32.UnmapViewOfFile(pBuf)
windll.kernel32.CloseHandle(hMapObject)
shmem.close()

Filename : SharedMemAccess.py

from ctypes import *
import mmap

FILE_MAP_ALL_ACCESS = 0xF001F
INVALID_HANDLE_VALUE = 0xFFFFFFFF
FALSE = 0
TRUE = 1
SHMEMSIZE = 256
szName = c_char_p("MyFileMappingObject")

hMapObject = windll.kernel32.OpenFileMappingA(FILE_MAP_ALL_ACCESS,
FALSE, szName)
if (hMapObject == 0):
print "Could not open file mapping object"
raise WinError()

pBuf = windll.kernel32.MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS,
0, 0, 0)

if (pBuf == 0):
print "Could not map view of file"
raise WinError()
else:
pBuf_str = cast(pBuf, c_char_p)
print pBuf_str.value

windll.kernel32.UnmapViewOfFile(pBuf)
windll.kernel32.CloseHandle(hMapObject)

shmem = mmap.mmap(0, 256, "MyFileMappingObject_ctypes",
mmap.ACCESS_READ)
print shmem.read(64)
shmem.close()


Source code to access shared memory, created in Python, from VC++
program

// Cplusplus_SharedMemoryAccess.cpp : Defines the entry point for the
console application.
//

#include "stdafx.h"
using namespace std;

#include <windows.h>
#include <memory.h>
#include <conio.h>
#include <stdio.h>

#define SHMEMSIZE 256

HANDLE hMapObject = NULL; // handle to file mapping
LPCTSTR pBuf;
TCHAR szName[]= TEXT("MyFileMappingObject");

int _tmain(int argc, _TCHAR* argv[])
{
hMapObject = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szName // name of mapping object
);

if (hMapObject == NULL || hMapObject == INVALID_HANDLE_VALUE) {
cout << "Could not open file mapping object " << GetLastError()
<< endl;
return 0;
}
pBuf = (LPTSTR) MapViewOfFile(hMapObject, // handle to mapping
object
FILE_MAP_ALL_ACCESS, // read/write
permission
0,
0,
SHMEMSIZE
);

if (pBuf == NULL)
{
cout << "Could not map view of file " << GetLastError() << endl;

return 0;
}

cout << "pBuf = " << pBuf << endl;
MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);

UnmapViewOfFile(pBuf);
CloseHandle(hMapObject);

return 0;
}
 
Joined
May 31, 2016
Messages
1
Reaction score
0
Hello,

at first, some information about my background.....I am relatively new to python and absolutely new to ctypes.
I am currently experimenting with ctypes to read data (telemetry data) from shared memory written by another program (the game Race07).
I know the structure of the data and created a corresponding structure in python:

class stru(Structure):
_fields_ = [
("float1", c_float),
("float2", c_float),
("float3", c_float),
("float4", c_float),
("float5", c_float),
("float6", c_float),
("engine_rps", c_float),
("max_engine_rps", c_float),
("fuel_pressure", c_float),
("fuel_left", c_float),
("fuel_capacity", c_float),
("engine_water_temp", c_float),
("engine_oil_temp", c_float),
("engine_oil_pressure", c_float),
("car_speed", c_float),
("number_of_laps", c_int32),
("completed_laps", c_int32),
("lap_time_best_self", c_float),
("lap_time_previous_self", c_float),
("lap_time_current_self", c_float),
("position", c_int32),
("num_cars", c_int32),
("gear", c_int32)
]

I already succeeded in opening the relevant shared memory handle (at least the related error message is not printed ;-)) using your example code above:

FILE_MAP_ALL_ACCESS = 0xF001F
INVALID_HANDLE_VALUE = 0xFFFFFFFF
SHMEMSIZE = sizeof(stru)
PAGE_READWRITE = 0x04
szName = create_string_buffer(b'$Race$')
szMsg = "Message from Python(ctypes) process"

hMapObject = windll.kernel32.CreateFileMappingA(INVALID_HANDLE_VALUE,
None, PAGE_READWRITE, 0, SHMEMSIZE, szName)
if (hMapObject == 0):
print ("Could not open file mapping object")
raise WinError()

pBuf = windll.kernel32.MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS,
0, 0, SHMEMSIZE)
if (pBuf == 0):
print ("Could not map view of file")
raise WinError()
else:


And now my question regarding the part after the "else":
How can I access the data in shared memory using my structure. In C, I would create a pointer of type "stru" and make it point to the memory address returned by "MapViewOfFile". But unfortunately I don't know how to
1) create such a pointer in python using ctypes
2) access the fields of the structure the pointer points to

I hope that I expressed my problem in an understandable way ;-)

Regards,
Mac
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,056
Messages
2,570,446
Members
47,101
Latest member
vaibhav87

Latest Threads

Top