1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
41
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
require 'dl'
module DL
module ValueUtil
def unsigned_value(val, ty)
case ty.abs
when TYPE_CHAR
[val].pack("c").unpack("C")[0]
when TYPE_SHORT
[val].pack("s!").unpack("S!")[0]
when TYPE_INT
[val].pack("i!").unpack("I!")[0]
when TYPE_LONG
[val].pack("l!").unpack("L!")[0]
when TYPE_LONG_LONG
[val].pack("q!").unpack("Q!")[0]
else
val
end
end
def signed_value(val, ty)
case ty.abs
when TYPE_CHAR
[val].pack("C").unpack("c")[0]
when TYPE_SHORT
[val].pack("S!").unpack("s!")[0]
when TYPE_INT
[val].pack("I!").unpack("i!")[0]
when TYPE_LONG
[val].pack("L!").unpack("l!")[0]
when TYPE_LONG_LONG
[val].pack("Q!").unpack("q!")[0]
else
val
end
end
def wrap_args(args, tys, funcs, &block)
result = []
tys ||= []
args.each_with_index{|arg, idx|
result.push(wrap_arg(arg, tys[idx], funcs, &block))
}
result
end
def wrap_arg(arg, ty, funcs, &block)
funcs ||= []
case arg
when CPtr
return arg.to_i
when IO
case ty
when TYPE_VOIDP
return CPtr[arg].to_i
else
return arg.to_i
end
when Function
if( block )
arg.bind_at_call(&block)
funcs.push(arg)
elsif !arg.bound?
raise(RuntimeError, "block must be given.")
end
return arg.to_i
when String
if( ty.is_a?(Array) )
return arg.unpack('C*')
else
case SIZEOF_VOIDP
when SIZEOF_LONG
return [arg].pack("p").unpack("l!")[0]
when SIZEOF_LONG_LONG
return [arg].pack("p").unpack("q")[0]
else
raise(RuntimeError, "sizeof(void*)?")
end
end
when Float, Integer
return arg
when Array
if( ty.is_a?(Array) ) # used only by struct
case ty[0]
when TYPE_VOIDP
return arg.collect{|v| Integer(v)}
when TYPE_CHAR
if( arg.is_a?(String) )
return val.unpack('C*')
end
end
return arg
else
return arg
end
else
if( arg.respond_to?(:to_ptr) )
return arg.to_ptr.to_i
else
begin
return Integer(arg)
rescue
raise(ArgumentError, "unknown argument type: #{arg.class}")
end
end
end
end
end
end
|