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:
<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.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