Назначение вложенных членов структуры в 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 ответ
Решение
Когда вы используете 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