ruby / fiddle

A libffi wrapper for Ruby.
BSD 2-Clause "Simplified" License
158 stars 36 forks source link

Question: How to allocate an array of structs? #95

Closed kojix2 closed 3 years ago

kojix2 commented 3 years ago

Hi!

How to allocate an array of structs? I tried the following code, but it does not work as expected. It may be because the same area is released twice.

require 'fiddle/import'

A = Fiddle::Importer.struct [
  'int x',
  'int y'
]

as = Fiddle::Pointer.malloc(A.size * 3)

structs = Array.new(3){ |i|
  size = A.size
  A.new(as.to_i + i * size, size)
}

Thank you.

kou commented 3 years ago

A.new's second argument is free function not size: A.new(as.to_i + i * size)

BTW, you must free as.

kojix2 commented 3 years ago

It's true. I was wrong.

require 'fiddle/import'

A = Fiddle::Importer.struct [
  'int x',
  'int y'
]

as = Fiddle::Pointer.malloc(A.size * 3)

structs = Array.new(3){ |i|
  size = A.size
  A.new(as.to_i + i * size)
}

When a Fiddle::Pointer is collected in garbage collection, is the memory of the pointer not automatically released? That is, if no function is specified to release it, it will remain until (or even after?) Ruby exits?

kou commented 3 years ago

You can use the second argument for Fiddle::Pointer.malloc for free function: Fiddle::Pointer.malloc(A.size * 3, Fiddle::RUBY_FREE).

You can also use block:

Fiddle::Pointer.malloc(A.size * 3, Fiddle::RUBY_FREE) do |as|
  # ...
end
kojix2 commented 3 years ago

Wow. This is very useful. Good to hear.