Subject: Re: [ruby-ffi] struct questions |
From: Wayne Meissner |
Date: 12/19/09 5:54 PM |
To: ruby-ffi@googlegroups.com |
2009/12/19 rogerdpack <rogerpack2005@gmail.com>:
With char arrays, it seems "difficult" to insert a string (rdb:1) ss[:title] = "abc" ArgumentError Exception: put not supported for FFI::StructLayout::Array is there an easier way than ss[:title][0] = 33; ss[:title][1] = 34; // one at a time?
Assuming you mean an array like this: class S < FFI::Struct layout :title, [ :char, 20 ] end Then currently the only easy way to fill it is: s[:title].to_ptr.put_string(0, "foo") Thats kinda ugly, so we should have an easier syntax. I have patches that make the following work for :char/:uchar arrays: s[:title] = "foo" s[:title] = [ 'f'.ord, 'o'.ord, 'o'.ord ] s[:title] = [ 1, 2, 3] The second form also works for all other array element types. The inverse also works for :char/:uchar arrays: s[:title].to_s # => "foo" There are a couple of corner cases that need to be figured out though. 1) What to do when a string + nul byte is larger than the array size a) raise an error b) do not terminate the string with a nul byte c) truncate the string and terminate with a nul byte Currently (a) is the preferred way (makes it consistent with put_string() e.g. class S < FFI::Struct layout :title, [ :char, 4 ] end s = S.new s[:title] = "abc" # works s[:title] = "test" # raises IndexError 2) Should array assignments be zero padded? i.e. class S < FFI::Struct layout :i, [ :int, 100 ] end s = S.new s[:i] = [ 1, 2, 3] Currently it zero pads the array if the source is smaller than the array field size. 3) Should over-sized array assignments raise an error or truncate? class S < FFI::Struct layout :i, [ :int, 2 ] end s = S.new s[:i] = [ 1, 2, 3] This currently raises an IndexError