diff --git a/lib/fiddle/struct.rb b/lib/fiddle/struct.rb index a766eba8..0e77a333 100644 --- a/lib/fiddle/struct.rb +++ b/lib/fiddle/struct.rb @@ -9,10 +9,24 @@ class CStruct include Enumerable # accessor to Fiddle::CStructEntity - def CStruct.entity_class + def self.entity_class CStructEntity end + def self.malloc(func=nil, &block) + if block + entity_class.malloc(types, func, size) do |entity| + block.call(new(entity)) + end + else + new(entity_class.malloc(types, func, size)) + end + end + + def initialize_copy(other) + @entity = other.to_ptr.dup + end + def each return enum_for(__function__) unless block_given? @@ -75,6 +89,16 @@ class CUnion def CUnion.entity_class CUnionEntity end + + def self.malloc(func=nil, &block) + if block + entity_class.malloc(types, func, size) do |entity| + block.call(new(entity)) + end + else + new(entity_class.malloc(types, func, size)) + end + end end # Wrapper for arrays within a struct @@ -183,15 +207,6 @@ def create(klass, types, members) size = entity_class.size(types) define_singleton_method(:alignment) { alignment } define_singleton_method(:size) { size } - define_singleton_method(:malloc) do |func=nil, &block| - if block - entity_class.malloc(types, func, size) do |entity| - block.call(new(entity)) - end - else - new(entity_class.malloc(types, func, size)) - end - end } return new_class end @@ -274,6 +289,12 @@ def initialize(addr, types, func = nil) super(addr, @size, func) end + # Initialize the memory for a struct and copy members from +other+. + def initialize_copy(other) + # TODO + super + end + # Set the names of the +members+ in this C struct def assign_names(members) @members = [] diff --git a/test/fiddle/test_cstruct.rb b/test/fiddle/test_cstruct.rb new file mode 100644 index 00000000..d71cc495 --- /dev/null +++ b/test/fiddle/test_cstruct.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +begin + require_relative 'helper' +rescue LoadError +end + +module Fiddle + class TestStruct < TestCase + # https://github.com/ruby/fiddle/issues/66 + def test_clone_gh_66 + s = Fiddle::Importer.struct(["int i"]) + a = s.malloc + a.i = 10 + b = a.clone + b.i = 20 + assert_equal({a: 10, b: 20}, + {a: a.i, b: b.i}) + end + end +end