Skip to content
chuckremes edited this page Sep 13, 2010 · 24 revisions

Traditionally with pointers you’ll have a method, like

attach_function :GetForeGroundWindow, [ ], :pointer

What this returns to you is a pointer that, probably, some other library is managing. You don’t need to release this pointer or anything.

To create your own pointer, do something like

a = MemoryPointer.new(4) # 4 bytes worth of memory

It will be freed when it is GC’ed or you call free.

a.address is the address it points at.

To copy some other pointer, it’s either

a = some_pointer

or

b = MemoryPointer.new(:pointer).write_pointer(some_pointer.read_pointer)

Handing off memory to external libraries

Some situations will require allocating native memory and handing off that buffer to an external library. The external library then handles the lifecycle of that buffer including eventually freeing it.

Wrap libc and use its malloc and free functions to allocate and free native memory.


module LibC
  extend FFI::Library
  LINUX = ["libc.so", "/usr/lib/libc.so"]
  OSX = ["libc.dylib", "/usr/lib/libc.dylib"]
  WINDOWS = [] # ??
  ffi_lib(LINUX + OSX + WINDOWS)

  # memory allocators
  attach_function :malloc, [:size_t], :pointer
  attach_function :calloc, [:size_t], :pointer
  attach_function :valloc, [:size_t], :pointer
  attach_function :realloc, [:pointer, :size_t], :pointer
  attach_function :free, [:pointer], :void

  # memory movers
  attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
  attach_function :bcopy, [:pointer, :pointer, :size_t], :void

end # module LibC

In the ruby code, calls to these functions will return FFI::Pointers.


foo = "a ruby string"
bar = 3.14159
baz = [1, 2, 3, 4, 5]

buffer1 = LibC.malloc foo.size
buffer1.write_string foo

buffer2 = LibC.malloc bar.size
buffer2.write_float bar

# all of the array elements need to be the same type
# meaning you can't mix ints, floats, strings, etc.
buffer3 = LibC.malloc(baz.first.size * baz.size)
buffer3.write_array_of_int baz
Clone this wiki locally