Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request read_array_of_struct or How to use ruby FFI to read array of static structures #956

Open
kojix2 opened this issue May 5, 2022 · 0 comments

Comments

@kojix2
Copy link
Contributor

kojix2 commented May 5, 2022

Hi!
Question and Feature request.

I searched Internet and found this answer.
How to use ruby FFI to read array of static structures

There's no particularly nice way, I'm afraid. read_array_of_type doesn't work for structs.

You can achieve this using simple pointer arithmetics:

def self.readDataArray
    pointer = myData
    array_of_structs = 3.times.map { |idx| 
        MyStruct.new(pointer + idx * MyStruct.size)
    }
    # Do your business
end

Yes. It works well. But, I think it would be nice to have methods like

  • read_array_of_struct
  • get_array_of_struct
module FFI
  class Pointer
    def read_array_of_struct(type, length)
      ary = []
      size = type.size
      tmp = self
      length.times { |j|
        ary << type.new(tmp)
        tmp += size unless j == length-1 # avoid OOB
      }
      ary
    end unless method_defined?(:read_array_of_struct)
  end
end

Usage

array = memory.read_array_of_struct(Foo::FFI::Bar, 3) 
# => [#<BAR>, #<BAR>, #<BAR>]

We have read_array_of_type. But it is not what I am looking for.

ffi/lib/ffi/pointer.rb

Lines 107 to 123 in 2cc0e53

# @param [Type] type type of data to read from pointer's contents
# @param [Symbol] reader method to send to +self+ to read +type+
# @param [Numeric] length
# @return [Array]
# Read an array of +type+ of length +length+.
# @example
# ptr.read_array_of_type(TYPE_UINT8, :read_uint8, 4) # -> [1, 2, 3, 4]
def read_array_of_type(type, reader, length)
ary = []
size = FFI.type_size(type)
tmp = self
length.times { |j|
ary << tmp.send(reader)
tmp += size unless j == length-1 # avoid OOB
}
ary
end unless method_defined?(:read_array_of_type)

Perhaps I missed a useful feature of ruby-ffi. If so, I'd be glad to know.

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant