首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Fiddle::CStructEntity

Parent:Fiddle::Pointer

一个C联合式包装

公共类方法

malloc(types, func = nil) Show source

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

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

代码语言:javascript
复制
# 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

代码语言:javascript
复制
# 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

代码语言:javascript
复制
Fiddle::CStructEntity.size(
  [ Fiddle::TYPE_DOUBLE,
    Fiddle::TYPE_INT,
    Fiddle::TYPE_CHAR,
    Fiddle::TYPE_VOIDP ]) #=> 24
代码语言:javascript
复制
# 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。[]

代码语言:javascript
复制
# 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#[] =

代码语言:javascript
复制
# 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结构中设置成员的名称

代码语言:javascript
复制
# File ext/fiddle/lib/fiddle/struct.rb, line 125
def assign_names(members)
  @members = members
end

set_ctypes(types) Show source

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

代码语言:javascript
复制
# 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

扫码关注腾讯云开发者

领取腾讯云代金券