Ruby 2.4

Fiddle::CStructEntity

class Fiddle::CStructEntity

Parent:Fiddle::Pointer

一个C联合式包装

公共类方法

malloc(types, func = nil) Show source

types提供的内容分配一个C结构。

当实例被废物收集时,C函数func被调用。

# File ext/fiddle/lib/fiddle/struct.rb, line 86 def CStructEntity.malloc(types, func = nil) addr = Fiddle.malloc(CStructEntity.size(types)) CStructEntity.new(addr, types, func) end

new(addr, types, func = nil) Show source

用指定类型将C指针addr包装为C结构体。

当实例被废物收集时,C函数func被调用。

另见Fiddle :: Pointer.new

调用超类方法Fiddle :: Pointer.new

# File ext/fiddle/lib/fiddle/struct.rb, line 119 def initialize(addr, types, func = nil) set_ctypes(types) super(addr, @size, func) end

size(types) Show source

返回给定的打包大小的偏移量types

Fiddle::CStructEntity.size( [ Fiddle::TYPE_DOUBLE, Fiddle::TYPE_INT, Fiddle::TYPE_CHAR, Fiddle::TYPE_VOIDP ]) #=> 24

# File ext/fiddle/lib/fiddle/struct.rb, line 98 def CStructEntity.size(types) offset = 0 max_align = types.map { |type, count = 1| last_offset = offset align = PackInfo::ALIGN_MAP[type] offset = PackInfo.align(last_offset, align) + (PackInfo::SIZE_MAP[type] * count) align }.max PackInfo.align(offset, max_align) end

公共实例方法

显示来源

读取结构成员 name

调用超类方法Fiddle :: Pointer。[]

# File ext/fiddle/lib/fiddle/struct.rb, line 151 def [](name) idx = @members.index(name) if( idx.nil? ) raise(ArgumentError, "no such member: #{name}") end ty = @ctypes[idx] if( ty.is_a?(Array) ) r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1]) else r = super(@offset[idx], SIZE_MAP[ty.abs]) end packer = Packer.new([ty]) val = packer.unpack([r]) case ty when Array case ty[0] when TYPE_VOIDP val = val.collect{|v| Pointer.new(v)} end when TYPE_VOIDP val = Pointer.new(val[0]) else val = val[0] end if( ty.is_a?(Integer) && (ty < 0) ) return unsigned_value(val, ty) elsif( ty.is_a?(Array) && (ty[0] < 0) ) return val.collect{|v| unsigned_value(v,ty[0])} else return val end end

[]=(name, val) Show source

将struct成员设置name为值val

调用超类方法Fiddle :: Pointer#[] =

# File ext/fiddle/lib/fiddle/struct.rb, line 185 def []=(name, val) idx = @members.index(name) if( idx.nil? ) raise(ArgumentError, "no such member: #{name}") end ty = @ctypes[idx] packer = Packer.new([ty]) val = wrap_arg(val, ty, []) buff = packer.pack([val].flatten()) super(@offset[idx], buff.size, buff) if( ty.is_a?(Integer) && (ty < 0) ) return unsigned_value(val, ty) elsif( ty.is_a?(Array) && (ty[0] < 0) ) return val.collect{|v| unsigned_value(v,ty[0])} else return val end end

assign_names(members) Show source

在此C结构中设置成员的名称

# File ext/fiddle/lib/fiddle/struct.rb, line 125 def assign_names(members) @members = members end

set_ctypes(types) Show source

计算结构中给定类型的偏移量和大小。

# File ext/fiddle/lib/fiddle/struct.rb, line 130 def set_ctypes(types) @ctypes = types @offset = [] offset = 0 max_align = types.map { |type, count = 1| orig_offset = offset align = ALIGN_MAP[type] offset = PackInfo.align(orig_offset, align) @offset << offset offset += (SIZE_MAP[type] * count) align }.max @size = PackInfo.align(offset, max_align) end