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