How to copy an instance of the Ruby Fiddle struct?

54 Views Asked by At

It's not obvious how to copy an instance of the Fiddle struct. I found an ugly solution using the Fiddle::Pointer like this.

require 'fiddle/import'

X = Fiddle::Importer.struct [
  'int a',
  'int b',
]

x = X.malloc
x.a = 1
x.b = 2

x2 = X.malloc
Fiddle::Pointer.new(x2.to_i)[0, X.size] = x.to_ptr.to_s
x2.b = 3
p [x.b, x2.b]

Is there a better way of doing this? One other way I thought of was using the []= operator of the super class(Fiddle::Pointer) of the x2.to_ptr, but it was worse than the above solution.

1

There are 1 best solutions below

1
On BEST ANSWER

The class returned by Fiddle::Importer.struct implements [] and []= to retrieve and set the struct members by name:

x['a'] #=> 1
x['b'] #=> 2

However, when called with 2 arguments, these methods behave like their Fiddle::Pointer counterparts and get / set the raw binary data:

x[0, 4] #=> "\x01\x00\x00\x00"   <- a's binary data
x[4, 4] #=> "\x02\x00\x00\x00"   <- b's binary data

x[4, 4] = [-5].pack('l') #=> "\xFB\xFF\xFF\xFF"
x.b #=> -5

To copy x's entire data to x2:

x2[0, X.size] = x[0, X.size]

x2.a #=> 1
x2.b #=> 2