Module: Fiddle::Importer
- Included in:
- LibUI::FFI
- Defined in:
- lib/libui/ffi.rb
Instance Method Summary collapse
Instance Method Details
#extern(signature, *opts) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/libui/ffi.rb', line 42 def extern(signature, *opts) symname, ctype, argtype, callback_argument_types = parse_signature(signature, type_alias) opt = (opts) func = import_function(symname, ctype, argtype, opt[:call_type]) func.callback_argument_types = callback_argument_types # Added # Ruby 2.7 Fiddle::Function dose not have @argument_types # Ruby 3.0 Fiddle::Function has @argument_types func.argument_types = argtype name = symname.gsub(/@.+/, '') @func_map[name] = func # define_method(name){|*args,&block| f.call(*args,&block)} begin /^(.+?):(\d+)/ =~ caller.first file = Regexp.last_match(1) line = Regexp.last_match(2).to_i rescue StandardError file, line = __FILE__, __LINE__ + 3 end module_eval(<<-EOS, file, line) def #{name}(*args, &block) @func_map['#{name}'].call(*args,&block) end EOS module_function(name) func end |
#parse_signature(signature, tymap = nil) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/libui/ffi.rb', line 15 def parse_signature(signature, tymap = nil) tymap ||= {} ctype, func, args = case compact(signature) when /^(?:[\w\*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/ [TYPE_VOIDP, Regexp.last_match(1), Regexp.last_match(2)] when /^([\w\*\s]+[*\s])(\w+)\((.*?)\);?$/ [parse_ctype(Regexp.last_match(1).strip, tymap), Regexp.last_match(2), Regexp.last_match(3)] else raise("can't parserake the function prototype: #{signature}") end symname = func callback_argument_types = {} # Added argtype = split_arguments(args).collect.with_index do |arg, idx| # Added with_index # Check if it is a function pointer or not if arg =~ /\(\*.*\)\(.*\)/ # Added # From the arguments, create a notation that looks like a function declaration # int(*f)(int *, void *) -> int f(int *, void *) func_arg = arg.sub('(*', ' ').sub(')', '') # Added # Use Fiddle's parse_signature method again. callback_argument_types[idx] = parse_signature(func_arg) # Added end parse_ctype(arg, tymap) end # Added callback_argument_types. Original method return only 3 values. [symname, ctype, argtype, callback_argument_types] end |