This technique may be useful if a native function that you are trying to attach has multiple signatures. For example, last argument in Win32 API function SendMessage (lParam) can be either :long or :pointer. You cannot directly tell FFI that this native function can be called with different types of arguments, so you need to attach this function twice with different names and signatures, and then write convenience method to check argument type and route call to attached function with appropriate signature:
require 'ffi'
module Win
extend FFI::Library
ffi_lib 'user32'
ffi_convention :stdcall
attach_function :SendMessageLong, :SendMessage, [:ulong, :uint, :uint, :long], :int
attach_function :SendMessagePointer, :SendMessage, [:ulong, :uint, :uint, :pointer], :int
def SendMessage(handle, msg, w_param, l_param)
case l_param
when Fixnum
SendMessageLong(handle, msg, w_param, l_param)
else
SendMessagePointer(handle, msg, w_param, l_param)
end
end
end
Type checking can be as elaborate as you want to. In the example above I only do light checking, routing calls with FixNum lParam to SendMessageLong and throwing everything else to pointer-typed SendMessagePointer. You can, for example, try to make sure that lParam quacks like :pointer, before routing call to SendMessagePointer. One of the ways to do it is to check if lParam responds to :address (key interface of any FFI::Pointer subclass or any custom pointer class)