Read FileMapping Object in python (adapted from c++)

1

I have a process that writes a FileMap to shared-memory, and want to access it in Python. I however have no idea what shape the filemap has.

I found a solution that works perfectly fine in c++, but there's a part I can't figure out because I'm not a c++ guy.

Simplified C++ code :

struct STelemetry {
    struct SHeader {
        char        Magic[32];             
        Nat32       Version;
        Nat32       Size;       
    };
};

#MAIN
HANDLE hMapFile = NULL;
void* pBufView = NULL;
const volatile STelemetry* Shared = NULL;

hMapFile = OpenFileMapping(FILE_MAP_READ, FALSE, "MP_Telemetry"); #FileMap Handle
pBufView = (void*)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 4096); #Pointer to MapView (string of bytes ?)
Shared = (const STelemetry*)pBufView; #Somehow cast string of bytes to class?

Full repo : https://github.com/Electron-x/TMTelemetry/blob/master/TMTelemetry.cpp

Which I adapted in Python :

from ctypes import *

FILE_MAP_ALL_ACCESS = 0xF001F
INVALID_HANDLE_VALUE = 0xFFFFFFFF
FALSE = 0
TRUE = 1
SHMEMSIZE = 4096 #Just copied this value form c++ code

hMapObject = windll.kernel32.OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, "MP_Telemetry") #OpenFileMappingA for ansi encoding, OpenFileMappingW for unicode

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

At that point, pBuf is a int value that I think represents the pointer, so I just want to read the value pointed to and create an object just like STelemetry in the C++ code. The C++ code does Shared = (const STelemetry*)pBufView; which I think has no equivalent in Python, so I tried to print it, thinking I could create a class from a string.

I tried various things :

import mmap

shmem = mmap.mmap(0, SHMEMSIZE, "ManiaPlanet_Telemetry", mmap.ACCESS_READ)
print(shmem.read(SHMEMSIZE).decode("utf-8")) # Using OpenFileMappingW
# If SHMEMSIZE = 256: MP_Telemetry              t  .    Stadium.....
# If SHMEMSIZE = 4096 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 40
print(shmem.read(SHMEMSIZE).decode("ansi")) # Using OpenFileMappingA
# MP_Telemetry              t  .    Stadium.....
shmem.close()

The "MP_Telemetry" and "Stadium" strings are things I want. But basically everything else is gibberish. Using the A function and Ansi seems better right ? But using the A function, pBuf = 0 always, so the pointer is null but still returns a string ? ... I've tried a bunch of other decoders and nothing more came out.

Other Solution :

x = cast(pBuf, c_char_p)
print(x.value)

But I get None using the A function and exit code 0xC0000005 (access denied) using the W function

So the question is : How do I interpret that byte string ? Is there a way to use the C++ defined class in Python (ctypes ?) And if you've got explanations for other points I did not get, you're welcome. (Also If you've got a better title, cause it may look like a duplicate)

Thanks

python
c++
shared-memory
asked on Stack Overflow Aug 29, 2019 by Josselin G.

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0