Burgestrand / spotify

Low-level Ruby bindings for libspotify, the official Spotify C API
https://rubygems.org/gems/spotify
Other
147 stars 17 forks source link

Handle API functions **:buffer_out** parameters #17

Closed r10r closed 10 years ago

r10r commented 10 years ago

Hi Kim,

what is the prefered way to handle the :buffer_out parameters? E.g

module Spotify
  class API
    attach_function :link_as_string, [ Link, :buffer_out, :int ], :int
  end
end

I'm not very familiar with ffi, but after looking at hallon I came up with the following solution:

  def track_uri(link)
      length = Spotify.link_as_string(link, link, 0)
      FFI::Buffer.alloc_out(length + 1) do |b|
        Spotify.link_as_string(link, b, b.size)
        return b.get_string(0).force_encoding("UTF-8")
      end
  end

Cheers, Ruben

Burgestrand commented 10 years ago

Looks about right, except that your calculation of the length passes in the link as second parameter, don’t do that.

buffer_out is a way for C functions to return multiple parameters. You pass the link as first parameter, and then you pass some space for the link_as_string function to fill for you, and how much space there is in it. For link_as_string, the return value is the size of the full link as a string, and the actual string is available to read from the second parameter you passed in.

Now that you bring it up, I believe I would like to get rid of as many of these buffer_out parameters as possible. I don’t feel there is any valid use-case where one would want to only read the length of a link, or where one would want to retrieve only part of a link.

PS: This issue would probably have been more suiting in the mailing list instead, but the mailing list link and contact information are a bit hidden in the README at the moment. I’ll fix that.