class FFI::Struct

Public Class Methods

alignment() click to toggle source

@return (see #alignment)

# File lib/ffi/struct.rb, line 164
def self.alignment
  @layout.alignment
end
auto_ptr() click to toggle source
# File lib/ffi/struct.rb, line 225
def self.auto_ptr
  @managed_type ||= Type::Mapped.new(ManagedStructConverter.new(self))
end
by_ref(flags = :inout) click to toggle source
# File lib/ffi/struct.rb, line 203
def self.by_ref(flags = :inout)
  self.ptr(flags)
end
by_value() click to toggle source
# File lib/ffi/struct.rb, line 199
def self.by_value
  self.val
end
in() click to toggle source
# File lib/ffi/struct.rb, line 183
def self.in
  ptr(:in)
end
layout(*spec) click to toggle source

@return [StructLayout] @overload layout

@return [StructLayout]
Get struct layout.

@overload layout(*spec)

@param [Array<Symbol, Integer>,Array(Hash)] spec
@return [StructLayout]
Create struct layout from +spec+.
@example Creating a layout from an array +spec+
  class MyStruct < Struct
    layout :field1, :int,
           :field2, :pointer,
           :field3, :string
  end
@example Creating a layout from an array +spec+ with offset
  class MyStructWithOffset < Struct
    layout :field1, :int,
           :field2, :pointer, 6,  # set offset to 6 for this field
           :field3, :string
  end
@example Creating a layout from a hash +spec+ (Ruby 1.9 only)
  class MyStructFromHash < Struct
    layout :field1 => :int,
           :field2 => :pointer,
           :field3 => :string
  end
@example Creating a layout with pointers to functions
  class MyFunctionTable < Struct
    layout :function1, callback([:int, :int], :int),
           :function2, callback([:pointer], :void),
           :field3, :string
  end
@note Creating a layout from a hash +spec+ is supported only for Ruby 1.9.
# File lib/ffi/struct.rb, line 266
def layout(*spec)
  #raise RuntimeError, "struct layout already defined for #{self.inspect}" if defined?(@layout)
  return @layout if spec.size == 0

  builder = StructLayoutBuilder.new
  builder.union = self < Union
  builder.packed = @packed if defined?(@packed)
  builder.alignment = @min_alignment if defined?(@min_alignment)

  if spec[0].kind_of?(Hash)
    hash_layout(builder, spec)
  else
    array_layout(builder, spec)
  end
  builder.size = @size if defined?(@size) && @size > builder.size
  cspec = builder.build
  @layout = cspec unless self == Struct
  @size = cspec.size
  return cspec
end
members() click to toggle source

(see FFI::Type#members)

# File lib/ffi/struct.rb, line 169
def self.members
  @layout.members
end
offset_of(name) click to toggle source

(see FFI::StructLayout#offset_of)

# File lib/ffi/struct.rb, line 179
def self.offset_of(name)
  @layout.offset_of(name)
end
offsets() click to toggle source

(see FFI::StructLayout#offsets)

# File lib/ffi/struct.rb, line 174
def self.offsets
  @layout.offsets
end
out() click to toggle source
# File lib/ffi/struct.rb, line 187
def self.out
  ptr(:out)
end
ptr(flags = :inout) click to toggle source
# File lib/ffi/struct.rb, line 191
def self.ptr(flags = :inout)
  @ref_data_type ||= Type::Mapped.new(StructByReference.new(self))
end
size() click to toggle source

Get struct size @return [Numeric]

# File lib/ffi/struct.rb, line 151
def self.size
  defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0
end
size=(size) click to toggle source

set struct size @param [Numeric] size @return [size]

# File lib/ffi/struct.rb, line 158
def self.size=(size)
  raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout)
  @size = size
end
val() click to toggle source
# File lib/ffi/struct.rb, line 195
def self.val
  @val_data_type ||= StructByValue.new(self)
end

Protected Class Methods

align(alignment = 1)
Alias for: aligned
aligned(alignment = 1) click to toggle source
# File lib/ffi/struct.rb, line 300
def aligned(alignment = 1)
  @min_alignment = alignment
end
Also aliased as: align
callback(params, ret) click to toggle source
# File lib/ffi/struct.rb, line 290
def callback(params, ret)
  mod = enclosing_module
  FFI::CallbackInfo.new(find_type(ret, mod), params.map { |e| find_type(e, mod) })
end
enclosing_module() click to toggle source
# File lib/ffi/struct.rb, line 305
def enclosing_module
  begin
    mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) }
    (mod < FFI::Library || mod < FFI::Struct || mod.respond_to?(:find_type)) ? mod : nil
  rescue Exception
    nil
  end
end
find_field_type(type, mod = enclosing_module) click to toggle source
# File lib/ffi/struct.rb, line 315
def find_field_type(type, mod = enclosing_module)
  if type.kind_of?(Class) && type < Struct
    FFI::Type::Struct.new(type)

  elsif type.kind_of?(Class) && type < FFI::StructLayout::Field
    type

  elsif type.kind_of?(::Array)
    FFI::Type::Array.new(find_field_type(type[0]), type[1])

  else
    find_type(type, mod)
  end
end
find_type(type, mod = enclosing_module) click to toggle source
# File lib/ffi/struct.rb, line 330
def find_type(type, mod = enclosing_module)
  if mod
    mod.find_type(type)
  end || FFI.find_type(type)
end
pack(packed = 1)
Alias for: packed
packed(packed = 1) click to toggle source
# File lib/ffi/struct.rb, line 295
def packed(packed = 1)
  @packed = packed
end
Also aliased as: pack

Private Class Methods

array_layout(builder, spec) click to toggle source

@param [StructLayoutBuilder] builder @param [Array<Symbol, Integer>] spec @return [builder] Add array spec to builder.

# File lib/ffi/struct.rb, line 354
def array_layout(builder, spec)
  i = 0
  while i < spec.size
    name, type = spec[i, 2]
    i += 2

    # If the next param is a Integer, it specifies the offset
    if spec[i].kind_of?(Integer)
      offset = spec[i]
      i += 1
    else
      offset = nil
    end

    builder.add name, find_field_type(type), offset
  end
end
hash_layout(builder, spec) click to toggle source

@param [StructLayoutBuilder] builder @param [Hash] spec @return [builder] @raise if Ruby 1.8 Add hash spec to builder.

# File lib/ffi/struct.rb, line 343
def hash_layout(builder, spec)
  raise "Ruby version not supported" if RUBY_VERSION =~ /1\.8\.*/
  spec[0].each do |name, type|
    builder.add name, find_field_type(type), nil
  end
end

Public Instance Methods

align()
Alias for: alignment
alignment() click to toggle source

@return [Fixnum] Struct alignment

# File lib/ffi/struct.rb, line 110
def alignment
  self.class.alignment
end
Also aliased as: align
clear() click to toggle source

Clear the struct content. @return [self]

# File lib/ffi/struct.rb, line 138
def clear
  pointer.clear
  self
end
members() click to toggle source

(see FFI::StructLayout#members)

# File lib/ffi/struct.rb, line 121
def members
  self.class.members
end
offset_of(name) click to toggle source

(see FFI::StructLayout#offset_of)

# File lib/ffi/struct.rb, line 116
def offset_of(name)
  self.class.offset_of(name)
end
offsets() click to toggle source

(see FFI::StructLayout#offsets)

# File lib/ffi/struct.rb, line 132
def offsets
  self.class.offsets
end
size() click to toggle source

Get struct size @return [Numeric]

# File lib/ffi/struct.rb, line 105
def size
  self.class.size
end
to_ptr() click to toggle source

Get {Pointer} to struct content. @return [AbstractMemory]

# File lib/ffi/struct.rb, line 145
def to_ptr
  pointer
end
values() click to toggle source

@return [Array] Get array of values from Struct fields.

# File lib/ffi/struct.rb, line 127
def values
  members.map { |m| self[m] }
end