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)}"