3

次の2つのFFI構造体について考えてみます。

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

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

それらをインスタンス化するには:

a = A.new
b = B.new

今、私がこのように割り当てようとするab.nested

b[:nested] = a

次のエラーが発生します。

ArgumentError: put not supported for FFI::StructByValue

ネストされた構造体が「値によってネストされている」場合、つまりポインタではない場合、FFIでは[]構文を使用して割り当てることができないようです。もしそうなら、どのように私はに割り当てるaのですb.nestedか?

4

1 に答える 1

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
于 2012-04-03T06:19:27.310 に答える