From: Andrea Fazzi Date: 2009-08-07T22:35:38+09:00 Subject: Re: FFI, sysctl, pointer question Thomas Chust wrote: > 2009/8/7 Andrea Fazzi : >> �[...] >> �tv_size_ptr = FFI::MemoryPointer.new(:int).write_int(tv.size) >> [...] > > Hello, > > size_t in ANSI C is required to be unsigned and is usually defined as > unsigned long. Therefore the above code is always wrong in that it > stores a signed integer, and it is likely wrong on some 64 bit systems > where an int is 32 bits wide but a long is 64 bits wide. > > cu, > Thomas Hi Thomas, I didn't check for the sysctl prototype when replied to OP so I was not aware about the type of the fourth argument (a pointer to a size_t value). Thank you for pointing it out. That said, the MemoryPointer object should be instantiated and filled in this way: tv_size_ptr = FFI::MemoryPointer.new(:size_t).write_size_t(tv.size) Doing this way, Ruby-FFI should use the right size for size_t. Unfortunately, AFAIK, while :size_t type exists its accessors (get_size_t, read_size_t, put_size_t, write_size_t) are not yet implemented on Ruby-FFI. I'll fire a JIRA ticket for this. Please also note that my previous code is not *always* wrong. Well, it may be conceptually wrong but not in practice for the considered case. In fact, size of the Timeval struct is 8 bytes on a ILP32 system and 16 bytes on a LP64 one. Thus, writing/reading a pointer to a signed 8 (or 16) is the same as writing/reading a pointer to an unsigned 8 (or 16). >> signed = FFI::MemoryPointer.new(:int).put_int(0, 8) => # >> signed.get_int(0) => 8 >> signed.get_uint(0) => 8 >> unsigned = FFI::MemoryPointer.new(:uint).put_uint(0, 8) => # >> unsigned.get_int(0) => 8 >> unsigned.get_uint(0) => 8 Andrea -- Posted via http://www.ruby-forum.com/.