I’m trying to rewrite some old C code that I had made around 10 years ago in Python 3.
This involves interfacing with SDL 2 via the ctypes module. I am aware that PySDL2 exists and I have used it, but would like to do this this way so that I can understand how to interface with any shared library/DLL.
The definition of an SDL_Surface in C is detailed at [SDL_Surface - SDL Wiki'](libsdl wiki)
I have defined it in Python as:-
class SDL_Surface(ctypes.Structure): _fields_ = (('flags', ctypes.c_uint), \ ('format', ctypes.c_void_p), \ ('w', ctypes.c_int), \ ('h', ctypes.c_int), \ ('pitch', ctypes.c_int), \ ('pixels', ctypes.POINTER(ctypes.c_ubyte)), \ ('userdata', ctypes.c_void_p), \ ('locked', ctypes.c_int), \ ('lock_data', ctypes.c_void_p), \ ('clip_rect', SDL_Rect), \ ('map', ctypes.c_void_p), \ ('refcount', ctypes.c_int))
Accessing the pixels via
instancename.contents.pixels[i] works, but is slow. A selective memcpy-style routine on a surface with 32-bit pixels of width and height 256 is slow enough on my i7 that the frame timing code doesn’t work properly.
I would like to instead create instances of
memoryview(instancename.contents.pixels) and try to make faster changes to pixels without creating copies with each operation, but this doesn’t work properly for two reasons:-
- The resulting memoryview instance is apparently only eight bytes in length, meaning it is likely looking at the pointer to the pixels instead of the pixels themselves;
- The format type of the memoryview is always ‘<B’. As I understand this, based on the documentation from the struct module, it equates to “little endian unsigned byte”. Endian-ness can only be applied to multi-byte integers, so to apply it to an array of singular bytes makes no sense. In addition, memoryview objects cannot operate on the format given and keep raising
NotImplementedError: memoryview: unsupported format <Bexceptions.
I can change the definition of the pixels field to
ctypes.POINTER(ctypes.c_void_p), but how do I obtain the correct address and length to be able to make a mutable memoryview from it?