Mercurial > pub > dyncall > bindings
comparison go/godc/godc_test.go @ 0:0cfcc391201f
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:26:28 +0100 |
parents | |
children | 9943c30ee2aa |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0cfcc391201f |
---|---|
1 /* | |
2 | |
3 godc_test.go | |
4 Copyright (c) 2014 Tassilo Philipp <tphilipp@potion-studios.com> | |
5 | |
6 Permission to use, copy, modify, and distribute this software for any | |
7 purpose with or without fee is hereby granted, provided that the above | |
8 copyright notice and this permission notice appear in all copies. | |
9 | |
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 | |
18 */ | |
19 | |
20 | |
21 package godc | |
22 | |
23 import ( | |
24 "testing" | |
25 "fmt" | |
26 "unsafe" | |
27 "math" | |
28 ) | |
29 | |
30 func TestGoDC(t *testing.T) { | |
31 lm := new(ExtLib) | |
32 if err := lm.Load("/usr/lib/libm.so"); err != nil { | |
33 t.FailNow() | |
34 } | |
35 defer lm.Free() | |
36 | |
37 if err := lm.SymsInit("/usr/lib/libm.so"); err != nil { | |
38 t.FailNow() | |
39 } | |
40 defer lm.SymsCleanup() | |
41 | |
42 fmt.Printf("Testing dl:\n") | |
43 fmt.Printf("-----------\n") | |
44 fmt.Printf("Loaded library at address: %p\n", lm.lib) | |
45 fmt.Printf("C sqrt function at address: %p\n", lm.FindSymbol("sqrt")) | |
46 fmt.Printf("C pow function at address: %p\n\n", lm.FindSymbol("pow")) | |
47 | |
48 fmt.Printf("Testing dlSyms:\n") | |
49 fmt.Printf("---------------\n") | |
50 fmt.Printf("Symbols in libm: %d\n", lm.SymsCount()) | |
51 fmt.Printf("Symbol name for address %p: %s\n", lm.FindSymbol("pow"), lm.SymsNameFromValue(lm.FindSymbol("pow"))) | |
52 fmt.Printf("All symbol names in libm:\n") | |
53 for i, n := 0, lm.SymsCount(); i<n; i++ { | |
54 fmt.Printf(" %s\n", lm.SymsName(i)) | |
55 } | |
56 fmt.Printf("\n") | |
57 | |
58 | |
59 | |
60 // Another lib | |
61 lc := new(ExtLib) | |
62 if err := lc.Load("/usr/lib/libc.so"); err != nil { | |
63 t.FailNow() | |
64 } | |
65 defer lc.Free() | |
66 | |
67 if err := lc.SymsInit("/usr/lib/libc.so"); err != nil { | |
68 t.FailNow() | |
69 } | |
70 defer lc.SymsCleanup() | |
71 | |
72 fmt.Printf("Symbols in libc: %d (not listing them here, too many)\n\n", lc.SymsCount()) | |
73 | |
74 | |
75 | |
76 // Call some functions | |
77 fmt.Printf("Testing dc:\n") | |
78 fmt.Printf("-----------\n") | |
79 vm := new(CallVM) | |
80 if err := vm.InitCallVM(); err != nil { | |
81 t.FailNow() | |
82 } | |
83 defer vm.Free() | |
84 | |
85 vm.Mode(DC_CALL_C_DEFAULT) | |
86 | |
87 | |
88 // Float | |
89 vm.Reset() | |
90 vm.ArgFloat(36) | |
91 rf := vm.CallFloat(lm.FindSymbol("sqrtf")) | |
92 fmt.Printf("sqrtf(36) = %f\n", rf) | |
93 if(rf != 6.0) { t.FailNow() } | |
94 | |
95 vm.Reset() // Test reset, reusing VM | |
96 vm.ArgDouble(3.6) | |
97 rd := vm.CallDouble(lm.FindSymbol("floor")) | |
98 fmt.Printf("floor(3.6) = %f\n", rd) | |
99 if(rd != 3.0) { t.FailNow() } | |
100 | |
101 | |
102 // Double | |
103 vm.Reset() | |
104 vm.ArgDouble(4.2373) | |
105 rd = vm.CallDouble(lm.FindSymbol("sqrt")) | |
106 fmt.Printf("sqrt(4.2373) = %f\n", rd) | |
107 if(math.Abs(rd - 2.05847) > 0.00001) { t.FailNow() } | |
108 | |
109 vm.Reset() | |
110 vm.ArgDouble(2.373) | |
111 vm.ArgDouble(-1000) // 2 args | |
112 rd = vm.CallDouble(lm.FindSymbol("copysign")) | |
113 fmt.Printf("copysign(2.373, -1000) = %f\n", rd) | |
114 if(rd != -2.373) { t.FailNow() } | |
115 | |
116 | |
117 // Strings | |
118 vm.Reset() | |
119 cs1 := vm.AllocCString("/return/only/this_here") | |
120 defer vm.FreeCString(cs1) | |
121 | |
122 vm.ArgPointer(cs1) | |
123 rs := vm.CallPointerToStr(lc.FindSymbol("basename")) | |
124 fmt.Printf("basename(\"/return/only/this_here\") = %s\n", rs) | |
125 if(rs != "this_here") { t.FailNow() } | |
126 // Reuse path | |
127 rs = vm.CallPointerToStr(lc.FindSymbol("dirname")) | |
128 fmt.Printf("dirname(\"/return/only/this_here\") = %s\n", rs) | |
129 if(rs != "/return/only") { t.FailNow() } | |
130 | |
131 | |
132 // Integer | |
133 vm.Reset() | |
134 vm.ArgInt('a') | |
135 ri := vm.CallInt(lc.FindSymbol("toupper")) | |
136 fmt.Printf("toupper('a') = %c\n", ri) | |
137 if(ri != 'A') { t.FailNow() } | |
138 | |
139 vm.Reset() | |
140 vm.ArgInt('a') | |
141 ri = vm.CallInt(lc.FindSymbol("tolower")) | |
142 fmt.Printf("tolower('a') = %c\n", ri) | |
143 if(ri != 'a') { t.FailNow() } | |
144 | |
145 vm.Reset() | |
146 vm.ArgInt('R') | |
147 ri = vm.CallInt(lc.FindSymbol("toupper")) | |
148 fmt.Printf("toupper('R') = %c\n", vm.CallInt(lc.FindSymbol("toupper"))) | |
149 if(ri != 'R') { t.FailNow() } | |
150 | |
151 vm.Reset() | |
152 vm.ArgInt('R') | |
153 ri = vm.CallInt(lc.FindSymbol("tolower")) | |
154 fmt.Printf("tolower('R') = %c\n", vm.CallInt(lc.FindSymbol("tolower"))) | |
155 if(ri != 'r') { t.FailNow() } | |
156 | |
157 | |
158 // Integer return | |
159 vm.Reset() | |
160 cs2 := vm.AllocCString("Tassilo") | |
161 defer vm.FreeCString(cs2) | |
162 | |
163 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand"))) | |
164 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand"))) | |
165 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand"))) | |
166 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand"))) | |
167 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand"))) | |
168 vm.ArgPointer(cs2) | |
169 ri = vm.CallInt(lc.FindSymbol("strlen")) | |
170 fmt.Printf("strlen(\"Tassilo\") = %d\n", ri) | |
171 if(ri != 7) { t.FailNow() } | |
172 | |
173 | |
174 // Formatted - with signature/conversion | |
175 vm.Reset() | |
176 vm.ArgF("dd)d", 3.14, -2000) // 2 args, second passed as int, but ArgF will convert | |
177 rd = vm.CallDouble(lm.FindSymbol("copysign")) | |
178 fmt.Printf("dd)d: copysign(3.14, -2000) = %f\n", rd) | |
179 if(rd != -3.14) { t.FailNow() } | |
180 | |
181 // Formatted - without signature/conversion | |
182 vm.Reset() | |
183 vm.ArgF("dd)d", -31.4, 42.4) // 2 args, second passed as int, but ArgF will convert | |
184 rd = vm.CallDouble(lm.FindSymbol("copysign")) | |
185 fmt.Printf("dd)d: copysign(-31.4, 42.4) = %f\n", rd) | |
186 if(rd != 31.4) { t.FailNow() } | |
187 | |
188 // Formatted - use Go's types, pass unsupported type, should return an error | |
189 vm.Reset() | |
190 err := vm.ArgF_Go(6.14, vm) | |
191 fmt.Printf("ArgF_Go: copysign(6.14, <unsupported type>) should return error: %t\n", err != nil) | |
192 if(err == nil) { t.FailNow() } | |
193 | |
194 // Formatted - use Go's types | |
195 vm.Reset() | |
196 vm.ArgF_Go(-61.4, 42.4) // 2 args, both need to be correct or undefined behaviour | |
197 rd = vm.CallDouble(lm.FindSymbol("copysign")) | |
198 fmt.Printf("copysign(-61.4, 42.4) = %f\n", rd) | |
199 if(rd != 61.4) { t.FailNow() } | |
200 | |
201 | |
202 // Ellipse | |
203 vm.Mode(DC_CALL_C_ELLIPSIS) | |
204 vm.Reset() | |
205 buf := make([]byte, 1000) | |
206 bufPtr := unsafe.Pointer(&buf[0]) | |
207 cs3 := vm.AllocCString("Four:%d | \"Hello\":%s | Pi:%f") | |
208 cs4 := vm.AllocCString("Hello") | |
209 defer vm.FreeCString(cs4) | |
210 defer vm.FreeCString(cs3) | |
211 | |
212 vm.ArgPointer(bufPtr) | |
213 vm.ArgPointer(cs3) | |
214 vm.Mode(DC_CALL_C_ELLIPSIS_VARARGS) | |
215 vm.ArgInt(4) | |
216 vm.ArgPointer(cs4) | |
217 vm.ArgDouble(3.14) // Double, b/c of ... promotion rules | |
218 ri = vm.CallInt(lc.FindSymbol("sprintf")) | |
219 fmt.Printf("sprintf(bufPtr, \"Four:%%d | \\\"Hello\\\":%%s | Pi:%%f\", 4, \"Hello\", 3.14) = %d:\n", ri) | |
220 fmt.Printf(" bufPtr: %s\n", string(buf[/*slice printed bytes*/:ri])) | |
221 if(ri != 36) { t.FailNow() } | |
222 | |
223 | |
224 //@@@ untested: | |
225 // - ArgF and ArgF_Go with strings | |
226 // - ArgF and ArgF_Go with bools | |
227 // - ... | |
228 } | |
229 |