On 02-Oct-16 23:44, eryk sun wrote:
  On Sun, Oct 2, 2016 at 5:50 PM, Michael Felt <mich...@felt.demon.nl> wrote:
a) where is documentation on "CField"'s?
It's undocumented.
So I do not feel so bad about not finding anything :)
A CField is a data descriptor that accesses a
struct field with the given type, size, and offset. Like most
descriptors, it's meant to be accessed as an attribute of an instance,
not as an attribute of the type.

When accessed as an attribute of a struct type, the value returned is
the CField descriptor itself. One reason to reference the descriptor
is for its "offset" attribute, since there's no offsetof() in ctypes.
At least in this regard it should be documented.

b) what I am not understanding - as the basic documentation shows FOO.value
as the way to set/get the value of a _field_
You may be surprised when accessing simple-type fields such as c_int
and c_char_p. These simple types have getter and setter functions that
get called automatically whenever the type is used as a function
result, array index, or struct field. For example:
OK - so lucky me - it "does not work" like earlier examples because I am referencing, generally, c_ulonglong - and these do not have a automatic getter/setter function? If not, how do I go about making one (preferably without needing to right a "method" for each and every _field_ in a class.
     class Foo(ctypes.Structure):
         _fields_ = (('v', ctypes.c_int),)

     >>> foo = Foo()
     >>> foo.v = 5
     >>> foo.v
     5

You can use a subclass to avoid the getfunc's automatic conversion. For example;

     class my_int(ctypes.c_int):
         pass

     class Bar(ctypes.Structure):
         _fields_ = (('v', my_int),)

     >>> bar = Bar()
     >>> bar.v = 5
     >>> bar.v
     <my_int object at 0x7f7385e8aae8>
     >>> bar.v.value
     5
I'll try it also with my c_int/c_uint fields - maybe these just work. If so, again - how do I get a c_ulonglong?

class time_t(Structure):
...
     if (maxsize > 2**32):
         _fields_ = [("v", c_long)]
     else:
         _fields_ = [("v", c_int)]
I'd alias the type instead of defining a struct, e.g. `time_t =
c_long`. This preserves automatic conversion of the simple type.
The reason for the not using alias is because a) I was trying to be more inline with the text of the include file. I will have to check the sizeof c_long (i.e., sizeof(long) in both 32 and 64-bit modes
Also, sys.maxsize is based on the platform's size_t type. That's
generally the same size as a pointer, but C doesn't require this.
Instead use sizeof(c_void_p), which will be 8 on a 64-bit platform and
4 on a 32-bit platform.
Thanks!

Also, while it's unrelated to your current problem, bear in mind that
int and long are both always 32-bit on Windows. c_int64 is a
cross-platform 64-bit integer.

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to