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