Subject:
[ruby-ffi] Re: mapping of unsigned char encoded_data[178][143] in a struct
From:
Wayne Meissner
Date:
8/1/11 10:18 PM
To:
ruby-ffi@googlegroups.com

2D arrays in structs are not supported by FFI - there's an issue for it (issue #18), but its not exactly a high priority, since only 2 people have asked for it in the last 2 years.

You can work around it by declaring a struct type for the array width, then declaring an array of that struct type.
e.g.

#require 'rubygems'
require 'ffi'

class DataArray < FFI::Struct
  layout :array, [ :uchar, 178 ]

  def [](idx)
    if idx.is_a?(Integer)
      self[:array][idx]
    else
      super(idx)
    end
  end

  def []=(idx, val)
    if idx.is_a?(Integer)
      self[:array][idx] = val
    else
      super(idx, val)
    end
  end
end

class Array2D < FFI::Struct
  layout :encoded_data, [ DataArray, 143 ]
end

ary = Array2D.new
ary[:encoded_data][0][0] = 0x1
ary[:encoded_data][0][1] = 0x2
ary[:encoded_data][0][2] = 0x3
ary[:encoded_data][1][0] = 0x4
ary[:encoded_data][2][0] = 0x5
ary[:encoded_data][3][0] = 0x6


puts "ary[:encoded_data][0][0]=#{ary[:encoded_data][0][0]}"
puts "ary[:encoded_data][0][1]=#{ary[:encoded_data][0][1]}" 
puts "ary[:encoded_data][1][0]=#{ary[:encoded_data][1][0]}"
# idx=178 should correspond to ary[:encoded_data][1][0]
puts "ary.pointer.get_char(178)=#{ary.pointer.get_char(178)}"
# idx=356 should correspond to ary[:encoded_data][2][0]
puts "ary.pointer.get_char(356)=#{ary.pointer.get_char(356)}"