Subject:
Re: [ruby-ffi] How to manage an Array of Structs
From:
Paolo Bosetti
Date:
4/27/11 11:10 PM
To:
ruby-ffi@googlegroups.com

Perfect! it works! now that I see it, the answer was easy.
Thanks a lot, Charles,
-P.



On Apr 27, 2011, at 5:41 PM, Charles Strahan wrote:

> Woops!
> 
> To get the bytes from the struct, you would want to do something like this:
> 
>   # Call Struct#pointer, and then Pointer#get_bytes
>   struct_bytes = op.pointer.get_bytes(0, Sembuf.size) # (offset, length)
> 
> -Charles
> 
> 
> On Wed, Apr 27, 2011 at 7:37 PM, Charles Strahan <charles.c.strahan@gmail.com> wrote:
> Hi P,
> 
> Just FYI, the first parameter to MemoryPointer.new is the type_size, and the second parameter is count - so you probably wanted to do something like this (for an array consisting of a single Sembuf):
> 
>   ops = FFI::MemoryPointer.new(Shared::Sembuf) # count defaults to 1
> 
> Now then, there's probably a better way to do this, but this should work:
> 
>   sembuf_count = ... # however many Sembufs you want to write
>   ops = FFI::MemoryPointer.new(Shared::Sembuf, sembuf_count)
> 
>   # get the bytes
>   struct_bytes = op.get_bytes(0, Sembuf.size) # (offset, length)
> 
>   # Pointer#[n] returns a new pointer with the address incremented by (n * Pointer#type_size) - just like a C array
>   ops[0].put_bytes(0, struct_bytes) # (offset, byte_string)
> 
>   # now you repeat with ops[1], ops[2], ops[n-1]
>   ops[1].put_bytes ..
>   ...
> 
> Again, there might be a better way to do this. I figured that Pointer#[]= would do the trick, but I guess not.
> 
> HTH,
> 
> Charles
> 
> 
> On Wed, Apr 27, 2011 at 11:58 AM, P4010 <paolo.bosetti@gmail.com> wrote:
> Hi all,
> I am writing an FFI interface to IP shared memory and semaphores. I
> wonder if someone here can give me advice on how to manage an Array of
> Structs.
> 
> I am mapping the semop() function in FFI. It has the following
> signature:
> 
> #include <sys/sem.h>
> int
> semop(int semid, struct sembuf *sops, size_t nsops);
> 
> I wrote something like:
> 
> module Shared
>  extend FFI::Library
>  ffi_lib FFI::Library::LIBC
> 
>  class Sembuf < FFI::Struct
>    layout :sem_num, :ushort,
>      :sem_op, :short,
>      :sem_flg, :short
>  end
> 
>  attach_function :semop,  [:int, :pointer, :size_t], :int
> 
> end
> 
> Now the Shared#semop wants a pointer to an array of Shared::Sembuf
> structs. How can I build such a pointer? I guess I should start with
> 
> op = Shared::Sembuf.new
> op[:sem_num] = 0
> op[:sem_op] = -1
> op[:sem_flg] = 0
> 
> ops = FFI::MemoryPointer.new(Shared::Sembuf, Shared::Sembuf.size * 1)
> 
> But then I could not find how to add the op instance to the array
> pointed to by ops...
> 
> I'll appreciate any suggestion...
> 
> Cheers,
> -P.
> 
>