Falcon SharedMemory via Python - FalconSharedMemoryAreaString
-
@SemlerPDX ChatGPT knows about Falcon BMS shared memory? Wild. I guess there’s enough on github for it…
-
@airtex2019 It knows “of” it, but doesn’t have all the information contained within the header files… but could copy them (in parts) to a chat, and then ask ChatGPT how to make use of them.
-
-
@SemlerPDX
Wow, I didn’t expect that, thanks.I have tried various things, but it’s still not working. Using your example, I am getting a ValueError:
Traceback (most recent call last): File "C:\Users\Me\Downloads\a.py", line 24, in <module> string = StringStruct.from_buffer_copy(data.data, offset) ValueError: Buffer size too small (1 instead of at least 16 bytes)
I think the problem is in the data itself. It seems to contain only b’\x00’. I think the issue is related to the data type.
ctypes.wintypes.CHAR
seems to be the wrong choice. According to the comment in the header it says:If you parse the data yourself, it should be handled as char[dataSize] by external apps
Unfortunately, ChatGPT didn’t provide much useful help with that.
Does anyone know what else I could try? -
import mmap import ctypes import ctypes.wintypes class StringStruct(ctypes.Structure): _fields_ = ( ("strId", ctypes.wintypes.UINT), ("strLength", ctypes.wintypes.UINT), ("strData", ctypes.c_char_p) ) class StringData(ctypes.Structure): _fields_ = ( ("VersionNum", ctypes.wintypes.UINT), ("NoOfStrings", ctypes.wintypes.UINT), ("dataSize", ctypes.wintypes.UINT), ("data", ctypes.POINTER(StringStruct)) ) buff = mmap.mmap(-1, ctypes.sizeof(StringData), "FalconSharedMemoryAreaString") data = StringData.from_buffer(buff) string_struct_array = ctypes.cast(data.data, ctypes.POINTER(StringStruct * data.NoOfStrings)) for i in range(data.NoOfStrings): print(ctypes.string_at(string_struct_array.contents[i].strData, string_struct_array.contents[i].strLength))
This is what I have now, but
string_struct_array[0].strId
orstring_struct_array[0].strData
isn’t outputting anything. What did I do wrong? -
@justonce01 AFAIR you need to read in the entire struct, since it is one consecutive piece of memory. I can’t really tell from this if you do that? Then you can read the individual elements, aka memory segments you need and cast to particular type.
Also, are you in 3D in BMS while reading ?
-
you need to read in the entire struct, since it is one consecutive piece of memory.
I think this is that part? data.data should be holding the struct, right? Sorry if these are stupid questions. I only know what seems to be the basics of Python (the books never mentioned anything about this “type” of programming).
string_struct_array = ctypes.cast(data.data, ctypes.POINTER(StringStruct * data.NoOfStrings))
Also, are you in 3D in BMS while reading ?
Yes. I checked with the bundled shared memory reader and it’s displaying everything correctly.
-
@justonce01 said in Falcon SharedMemory via Python - FalconSharedMemoryAreaString:
you need to read in the entire struct, since it is one consecutive piece of memory.
I think this is that part? data.data should be holding the struct, right?
As far as I can tell, you allocate memory for only 4 fields - from a quick glance at the flightdata.h it has a lot more. But maybe I don’t quite understand the Python here
-
@justonce01 Did you see my earlier reply? Sorry if not helpful.
I was trying to say, I don’t think you’re going to be able to parse this blob with declarative interop – you’re going to have to write procedural code to walk that packed sequence of length-prefixed-but-also-null-terminated-char[] strings.
The comment on line 879 is the salient point.
// Note that this can NOT be treated as StringStruct[NoOfStrings] by external apps, due to the flexible size of StringStruct!
[Edit: I see https://docs.python.org/3/library/ctypes.html#variable-sized-data-types has a little bit to say on how to handle variable-sized types. But not sure it’s sufficient in this case.]
-
@jayb
It’s just the FalconSharedMemoryAreaString part of it. I’m not sure, but I don’t think that all the other areas have to be mapped as well every time (at least judging from the examples I have seen online).@airtex2019
Yes, but I couldn’t make much out of it. I will consider that and see if it will bring me closer to solving this. Thanks. -
@justonce01 again I don’t know Python well enough to say if something is impossible … but even C# which has the most comprehensive C/C++ interop support I know of… I don’t think it’s possible to handle a dynamically-sized struct composed of array of dynamically-sized structs, containing embedded null-term strings.
The C# code from lightningstools had to resort to a for-loop to unpack this section.
-
@justonce01 have you seen this? It may do everything you need?
https://github.com/nmeier/simscript/blob/master/modules/falcon.py
-
@S3NTRY
Yes, that one has been pretty helpful, I basically copied everything from there. But unfortunately that one is lacking the FalconSharedMemoryAreaString part as well. There’s an open issue regarding that, perhaps someone with more knowledge might eventually chime in and figure it out.