在Ruby FFI中分配给嵌套的struct成员

时间:2012-04-03 01:57:27

标签: ruby struct ruby-ffi

考虑以下两个FFI结构:

class A < FFI::Struct
layout :data, :int
end 

class B < FFI::Struct
layout :nested, A
end

要实例化它们:

a = A.new
b = B.new

现在,当我尝试将a分配给b.nested时,就像这样:

b[:nested] = a

我收到以下错误:

ArgumentError: put not supported for FFI::StructByValue

如果嵌套结构“按值嵌套”,那么FFI似乎不允许使用[]语法进行分配,即它不是指针。如果是,那么如何将a分配给b.nested

1 个答案:

答案 0 :(得分:3)

当您使用FFI进行嵌套时,它可以像这样工作:

b = B.new
b[:nested][:data] = 42
b[:nested][:data] #=> 42

FFI“b”对象创建了自己的“a”对象;你不需要创建自己的。

您尝试做的是创建自己的“a”对象然后存储它:

a = A.new
b = B.new
b[:nested] = a  #=> fails because "a" is a Ruby object, not a nested value

解决方案是将“a”存储为指针:

require 'ffi'

class A < FFI::Struct
  layout :data, :int
end

class B < FFI::Struct
  layout :nested, :pointer  # we use a pointer, not a class
end

a = A.new
b = B.new

# Set some arbitrary data
a[:data] = 42

# Set :nested to the pointer to the "a" object
b[:nested] = a.pointer

# To prove it works, create a new object with the pointer
c = A.new(b[:nested])

# And prove we can get the arbitrary data    
puts c[:data]  #=> 42