Subject:
[ruby-ffi] Behavior of ffi_lib with Arrays (Was: lists only one lib?)
From:
John Croisant
Date:
12/21/09 4:49 PM
To:
ruby-ffi@googlegroups.com

On Sat, Dec 19, 2009 at 6:35 AM, Wayne Meissner <wmeissner@gmail.com> wrote:
> You need to list them all on the same line.
>
> i.e.
>
>  ffi_lib 'user32', 'msvcrt'

I always thought that giving multiple args to ffi_lib was a way of
providing fallback libraries /alternate names in case the first one
failed. I guess I assumed that it didn't make sense (or wouldn't work)
to load more than one library into the same module, anyway. I'm not
sure why I assumed that, though.

Actually, looking at the code... it seems like it was written to
possibly expect to be given an Array (or even multiple Arrays), and
only to load the first library per array that succeeds. I guess that's
what confused me.

Simplified code to show what I mean:

> def ffi_lib(*names)
>   ffi_libs = names.map do |name|
>     libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
>
>     libnames.each do |libname|
>       lib = FFI::DynamicLibrary.open(libname, ...)
>       break if lib
>     end
>
>     # return the found lib
>     lib
>   end
>
>   @ffi_libs = ffi_libs
> end

Digging through the commit history, it looks like this was carried
over from a time when ffi_lib expected an explicit array of library
names. Is the Array form still supported? If not, the ffi_lib function
can be simplified. If yes, there is a TypeError when passing an Array
that should be fixed:

> module SDL
>   extend FFI::Library
>   ffi_lib ["SDL"]
> end

> TypeError: can't convert Array into String
> 	from /usr/lib/ruby19/gems/1.9.1/gems/ffi-0.5.4/lib/ffi/ffi.rb:61:in `basename'
> 	from /usr/lib/ruby19/gems/1.9.1/gems/ffi-0.5.4/lib/ffi/ffi.rb:61:in `map_library_name'
> 	from /usr/lib/ruby19/gems/1.9.1/gems/ffi-0.5.4/lib/ffi/library.rb:8:in `block in ffi_lib'
> 	from /usr/lib/ruby19/gems/1.9.1/gems/ffi-0.5.4/lib/ffi/library.rb:7:in `each'
> 	from /usr/lib/ruby19/gems/1.9.1/gems/ffi-0.5.4/lib/ffi/library.rb:7:in `ffi_lib'


- John