Reputation: 1340
I am trying to make a dynamic struct class. The problem with a ctypes struct is that there is a finalization process that takes place when the struct is initialized or when fields is set.
In the test scripts of the ctypes source I have found this:
Structure/Union classes must get 'finalized' sooner or later, when one of these things happen:
- _fields_ is set.
- An instance is created.
- The type is used as field of another Structure/Union.
- The type is subclassed
When they are finalized, assigning fields is no longer allowed.
The structs are used for function pointers. In the subclass of Structure i have defined helper functions that fill a temporary array (not _fields_) with the values that should end up in the _fields_ variable.
This will allow users of my script to make a struct without subclassing it with something like:
class Sub (Structure)
_fields_ = [
(<func_name>, CFUNCTYPE(<res>,<*args>)),
(...),
]
Sub(CFUNCTYPE(<res>, <*args>)(<func_impl>), ...)
But instead use:
class Sub(function_struct):
pass
Sub.addFunction(...)
Sub(<func_impl>)
In the init function of my subclass I do set the _fields_ attribute, which should finalize the type. However, the fields added in the __init__ function do not appear as attributes. Giving me errors like 'Sub' object has no attribute '<func_name>'
I suspect that the subclass is already finalized before the __init__ call, either through #2 or #4 of my list.
Is there any way to work around the finalization or delay it enough for me to dynamically set the _fields_ attribute?
Upvotes: 0
Views: 269
Reputation: 1340
I have worked around my issue by making a factory class.
factory = structFactory()
factory.addFunction(<name>, <rtype>)
# Also redefines the __init__ function before returning the type
structType = factory.getType()
struct = structType(<impl>)
The struct can also be created from a memory address with ctypes.cast
and structType.from_address
.
Upvotes: 0