Class: FFI::Struct

Inherits:
Object
  • Object
show all
Defined in:
ext/ffi_c/Struct.c,
lib/ffi/struct.rb,
ext/ffi_c/Struct.c

Overview

A FFI::Struct means to mirror a C struct.

A Struct is defined as:

class MyStruct < FFI::Struct
  layout :value1, :int,
         :value2, :double
end

and is used as:

my_struct = MyStruct.new
my_struct[:value1] = 12

For more information, see github.com/ffi/ffi/wiki/Structs

Direct Known Subclasses

ManagedStruct, Union

Defined Under Namespace

Classes: InlineArray, ManagedStructConverter

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.alignmentFixnum



164
165
166
# File 'lib/ffi/struct.rb', line 164

def self.alignment
  @layout.alignment
end

.array_layout(builder, spec) ⇒ builder (private)

Add array spec to builder.



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/ffi/struct.rb', line 348

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

.auto_ptrObject



225
226
227
# File 'lib/ffi/struct.rb', line 225

def self.auto_ptr
  @managed_type ||= Type::Mapped.new(ManagedStructConverter.new(self))
end

.by_ref(flags = :inout) ⇒ Object



203
204
205
# File 'lib/ffi/struct.rb', line 203

def self.by_ref(flags = :inout)
  self.ptr(flags)
end

.by_valueObject



199
200
201
# File 'lib/ffi/struct.rb', line 199

def self.by_value
  self.val
end

.hash_layout(builder, spec) ⇒ builder (private)

Add hash spec to builder.

Raises:

  • if Ruby 1.8



337
338
339
340
341
342
# File 'lib/ffi/struct.rb', line 337

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

.inObject



183
184
185
# File 'lib/ffi/struct.rb', line 183

def self.in
  ptr(:in)
end

.layoutStructLayout .layout(*spec) ⇒ StructLayout

Overloads:

  • .layoutStructLayout

    Get struct layout.

  • .layout(*spec) ⇒ StructLayout
    Note:

    Creating a layout from a hash spec is supported only for Ruby 1.9.

    Create struct layout from spec.

    Examples:

    Creating a layout from an array spec

    class MyStruct < Struct
      layout :field1, :int,
             :field2, :pointer,
             :field3, :string
    end

    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

    Creating a layout from a hash spec (Ruby 1.9 only)

    class MyStructFromHash < Struct
      layout :field1 => :int,
             :field2 => :pointer,
             :field3 => :string
    end


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/ffi/struct.rb', line 260

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

.membersObject



169
170
171
# File 'lib/ffi/struct.rb', line 169

def self.members
  @layout.members
end

.offset_of(name) ⇒ Numeric

Get the offset of a field.



179
180
181
# File 'lib/ffi/struct.rb', line 179

def self.offset_of(name)
  @layout.offset_of(name)
end

.offsetsArray<Array(Symbol, Numeric)>

Get an array of tuples (field name, offset of the field).



174
175
176
# File 'lib/ffi/struct.rb', line 174

def self.offsets
  @layout.offsets
end

.outObject



187
188
189
# File 'lib/ffi/struct.rb', line 187

def self.out
  ptr(:out)
end

.ptr(flags = :inout) ⇒ Object



191
192
193
# File 'lib/ffi/struct.rb', line 191

def self.ptr(flags = :inout)
  @ref_data_type ||= Type::Mapped.new(StructByReference.new(self))
end

.sizeNumeric

Get struct size



151
152
153
# File 'lib/ffi/struct.rb', line 151

def self.size
  defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0
end

.size=(size) ⇒ size

set struct size

Raises:

  • (ArgumentError)


158
159
160
161
# File 'lib/ffi/struct.rb', line 158

def self.size=(size)
  raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout)
  @size = size
end

.valObject



195
196
197
# File 'lib/ffi/struct.rb', line 195

def self.val
  @val_data_type ||= StructByValue.new(self)
end

Instance Method Details

#alignFixnum



113
114
115
# File 'lib/ffi/struct.rb', line 113

def alignment
  self.class.alignment
end

#alignmentFixnum



110
111
112
# File 'lib/ffi/struct.rb', line 110

def alignment
  self.class.alignment
end

#clearself

Clear the struct content.



138
139
140
141
# File 'lib/ffi/struct.rb', line 138

def clear
  pointer.clear
  self
end

#membersArray<Symbol>

Get list of field names.



121
122
123
# File 'lib/ffi/struct.rb', line 121

def members
  self.class.members
end

#offset_of(name) ⇒ Numeric

Get the offset of a field.



116
117
118
# File 'lib/ffi/struct.rb', line 116

def offset_of(name)
  self.class.offset_of(name)
end

#offsetsArray<Array(Symbol, Numeric)>

Get an array of tuples (field name, offset of the field).



132
133
134
# File 'lib/ffi/struct.rb', line 132

def offsets
  self.class.offsets
end

#sizeNumeric

Get struct size



105
106
107
# File 'lib/ffi/struct.rb', line 105

def size
  self.class.size
end

#to_ptrAbstractMemory

Get Pointer to struct content.



145
146
147
# File 'lib/ffi/struct.rb', line 145

def to_ptr
  pointer
end

#valuesArray

Get array of values from Struct fields.



127
128
129
# File 'lib/ffi/struct.rb', line 127

def values
  members.map { |m| self[m] }
end