1require 'dl' 2 3module DL 4 module ValueUtil 5 def unsigned_value(val, ty) 6 case ty.abs 7 when TYPE_CHAR 8 [val].pack("c").unpack("C")[0] 9 when TYPE_SHORT 10 [val].pack("s!").unpack("S!")[0] 11 when TYPE_INT 12 [val].pack("i!").unpack("I!")[0] 13 when TYPE_LONG 14 [val].pack("l!").unpack("L!")[0] 15 when TYPE_LONG_LONG 16 [val].pack("q").unpack("Q")[0] 17 else 18 val 19 end 20 end 21 22 def signed_value(val, ty) 23 case ty.abs 24 when TYPE_CHAR 25 [val].pack("C").unpack("c")[0] 26 when TYPE_SHORT 27 [val].pack("S!").unpack("s!")[0] 28 when TYPE_INT 29 [val].pack("I!").unpack("i!")[0] 30 when TYPE_LONG 31 [val].pack("L!").unpack("l!")[0] 32 when TYPE_LONG_LONG 33 [val].pack("Q").unpack("q")[0] 34 else 35 val 36 end 37 end 38 39 def wrap_args(args, tys, funcs, &block) 40 result = [] 41 tys ||= [] 42 args.each_with_index{|arg, idx| 43 result.push(wrap_arg(arg, tys[idx], funcs, &block)) 44 } 45 result 46 end 47 48 def wrap_arg(arg, ty, funcs = [], &block) 49 require 'dl/func' 50 51 funcs ||= [] 52 case arg 53 when nil 54 return 0 55 when CPtr 56 return arg.to_i 57 when IO 58 case ty 59 when TYPE_VOIDP 60 return CPtr[arg].to_i 61 else 62 return arg.to_i 63 end 64 when Function 65 if( block ) 66 arg.bind_at_call(&block) 67 funcs.push(arg) 68 elsif !arg.bound? 69 raise(RuntimeError, "block must be given.") 70 end 71 return arg.to_i 72 when String 73 if( ty.is_a?(Array) ) 74 return arg.unpack('C*') 75 else 76 case SIZEOF_VOIDP 77 when SIZEOF_LONG 78 return [arg].pack("p").unpack("l!")[0] 79 when SIZEOF_LONG_LONG 80 return [arg].pack("p").unpack("q")[0] 81 else 82 raise(RuntimeError, "sizeof(void*)?") 83 end 84 end 85 when Float, Integer 86 return arg 87 when Array 88 if( ty.is_a?(Array) ) # used only by struct 89 case ty[0] 90 when TYPE_VOIDP 91 return arg.collect{|v| Integer(v)} 92 when TYPE_CHAR 93 if( arg.is_a?(String) ) 94 return val.unpack('C*') 95 end 96 end 97 return arg 98 else 99 return arg 100 end 101 else 102 if( arg.respond_to?(:to_ptr) ) 103 return arg.to_ptr.to_i 104 else 105 begin 106 return Integer(arg) 107 rescue 108 raise(ArgumentError, "unknown argument type: #{arg.class}") 109 end 110 end 111 end 112 end 113 end 114end 115