Search code examples
methodssyntaxsemanticscrystal-lang

What am I supposed to pass to the following method in Crystal?


Background

I'm trying to use some Cairo bindings for Crystal, but I'm having some trouble with the syntax and how to call the method below. It is implemented as such:

# Inside Module Cairo, class Surface

# ...

def write_to_png_stream(write_func : LibCairo::WriteFuncT, closure : Void*) : Status
   Status.new(LibCairo.surface_write_to_png_stream(@surface, write_func, closure).value)
end
# Inside Module LibCairo

# ...

enum StatusT
  SUCCESS = 0

  NO_MEMORY
  INVALID_RESTORE
  # ...
end

# ...

alias WriteFuncT = Void*, UInt8*, UInt32 -> StatusT

# ...

fun surface_write_to_png_stream = cairo_surface_write_to_png_stream(
  surface : PSurfaceT,
  write_func : WriteFuncT,
  closure : Void*
) : StatusT

Question

Specifically, I'm asking how to call the Cairo::Surface#write_to_png_stream method. What do I pass as the write_func:LibCairo::WriteFuncT? What do I pass as the closure: Void*?

I tried with the following but I haven't managed to get it to work...

def my_write_func(a : Void*, b : UInt8*, c : UInt32) : Cairo::C::LibCairo::StatusT
   puts a
   puts b
   puts c

   Cairo::C::LibCairo::StatusT::SUCCESS
end

surface = Cairo::Surface.new Cairo::Format::ARGB32, 400, 300
ctx = Cairo::Context.new surface

ctx.set_source_rgba 1.0, 0.0, 1.0, 1.0
ctx.rectangle 0.0, 0.0, 400.0, 300.0
ctx.fill

# here, how do I call surface.write_to_png_stream passing my 'my_write_func'?
# a Proc doesn't seem to work.. ( ->my_write_func(Void*, UInt8*, UInt32) )

surface.finish

Solution

  • Finally I got it working.. Or well, I managed to call it at least.

    surface.write_to_png_stream ->my_write_func(Void*, UInt8*, UInt32), Pointer(Void).null
    

    It turns out it was a Proc afterall as I suspected and that I just needed a null Pointer too. For future reference, I have an issue at the repo talking about the specific usage of this method, but I suppose the syntax/semantics question is answered here on SO.