Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

fiddle.c
Go to the documentation of this file.
1 #include <fiddle.h>
2
3 VALUE mFiddle;
4 VALUE rb_eFiddleError;
5
6 #ifndef TYPE_SSIZE_T
7 # if SIZEOF_SIZE_T == SIZEOF_INT
8 # define TYPE_SSIZE_T TYPE_INT
9 # elif SIZEOF_SIZE_T == SIZEOF_LONG
10 # define TYPE_SSIZE_T TYPE_LONG
11 # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
12 # define TYPE_SSIZE_T TYPE_LONG_LONG
13 # endif
14 #endif
15 #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
16
17 #ifndef TYPE_PTRDIFF_T
18 # if SIZEOF_PTRDIFF_T == SIZEOF_INT
19 # define TYPE_PTRDIFF_T TYPE_INT
20 # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
21 # define TYPE_PTRDIFF_T TYPE_LONG
22 # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
23 # define TYPE_PTRDIFF_T TYPE_LONG_LONG
24 # endif
25 #endif
26
27 #ifndef TYPE_INTPTR_T
28 # if SIZEOF_INTPTR_T == SIZEOF_INT
29 # define TYPE_INTPTR_T TYPE_INT
30 # elif SIZEOF_INTPTR_T == SIZEOF_LONG
31 # define TYPE_INTPTR_T TYPE_LONG
32 # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
33 # define TYPE_INTPTR_T TYPE_LONG_LONG
34 # endif
35 #endif
36 #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
37
38 void Init_fiddle_pointer(void);
39
40 /*
41 * call-seq: Fiddle.malloc(size)
42 *
43 * Allocate +size+ bytes of memory and return the integer memory address
44 * for the allocated memory.
45 */
46 static VALUE
47 rb_fiddle_malloc(VALUE self, VALUE size)
48 {
49 void *ptr;
50
51 rb_secure(4);
52 ptr = (void*)ruby_xmalloc(NUM2INT(size));
53 return PTR2NUM(ptr);
54 }
55
56 /*
57 * call-seq: Fiddle.realloc(addr, size)
58 *
59 * Change the size of the memory allocated at the memory location +addr+ to
60 * +size+ bytes. Returns the memory address of the reallocated memory, which
61 * may be different than the address passed in.
62 */
63 static VALUE
64 rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
65 {
66 void *ptr = NUM2PTR(addr);
67
68 rb_secure(4);
69 ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
70 return PTR2NUM(ptr);
71 }
72
73 /*
74 * call-seq: Fiddle.free(addr)
75 *
76 * Free the memory at address +addr+
77 */
78 VALUE
79 rb_fiddle_free(VALUE self, VALUE addr)
80 {
81 void *ptr = NUM2PTR(addr);
82
83 rb_secure(4);
84 ruby_xfree(ptr);
85 return Qnil;
86 }
87
88 /*
89 * call-seq: Fiddle.dlunwrap(addr)
90 *
91 * Returns the hexadecimal representation of a memory pointer address +addr+
92 *
93 * Example:
94 *
95 * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
96 * => #<Fiddle::Handle:0x00000001342460>
97 *
98 * lib['strcpy'].to_s(16)
99 * => "7f59de6dd240"
100 *
101 * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
102 * => "7f59de6dd240"
103 */
104 VALUE
105 rb_fiddle_ptr2value(VALUE self, VALUE addr)
106 {
107 rb_secure(4);
108 return (VALUE)NUM2PTR(addr);
109 }
110
111 /*
112 * call-seq: Fiddle.dlwrap(val)
113 *
114 * Returns a memory pointer of a function's hexadecimal address location +val+
115 *
116 * Example:
117 *
118 * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
119 * => #<Fiddle::Handle:0x00000001342460>
120 *
121 * Fiddle.dlwrap(lib['strcpy'].to_s(16))
122 * => 25522520
123 */
124 static VALUE
125 rb_fiddle_value2ptr(VALUE self, VALUE val)
126 {
127 return PTR2NUM((void*)val);
128 }
129
130 void Init_fiddle_handle(void);
131
132 void
133 Init_fiddle(void)
134 {
135 /*
136 * Document-module: Fiddle
137 *
138 * A libffi wrapper for Ruby.
139 *
140 * == Description
141 *
142 * Fiddle is an extension to translate a foreign function interface (FFI)
143 * with ruby.
144 *
145 * It wraps {libffi}[http://sourceware.org/libffi/], a popular C library
146 * which provides a portable interface that allows code written in one
147 * language to clal code written in another language.
148 *
149 * == Example
150 *
151 * Here we will use Fiddle::Function to wrap {floor(3) from
152 * libm}[http://linux.die.net/man/3/floor]
153 *
154 * require 'fiddle'
155 *
156 * libm = Fiddle.dlopen('/lib/libm.so.6')
157 *
158 * floor = Fiddle::Function.new(
159 * libm['floor'],
160 * [Fiddle::TYPE_DOUBLE],
161 * Fiddle::TYPE_DOUBLE
162 * )
163 *
164 * puts floor.call(3.14159) #=> 3.0
165 *
166 *
167 */
168 mFiddle = rb_define_module("Fiddle");
169
170 /*
171 * Document-class: Fiddle::DLError
172 *
173 * standard dynamic load exception
174 */
175 rb_eFiddleError = rb_define_class_under(mFiddle, "DLError", rb_eStandardError);
176
177 /* Document-const: TYPE_VOID
178 *
179 * C type - void
180 */
181 rb_define_const(mFiddle, "TYPE_VOID", INT2NUM(TYPE_VOID));
182
183 /* Document-const: TYPE_VOIDP
184 *
185 * C type - void*
186 */
187 rb_define_const(mFiddle, "TYPE_VOIDP", INT2NUM(TYPE_VOIDP));
188
189 /* Document-const: TYPE_CHAR
190 *
191 * C type - char
192 */
193 rb_define_const(mFiddle, "TYPE_CHAR", INT2NUM(TYPE_CHAR));
194
195 /* Document-const: TYPE_SHORT
196 *
197 * C type - short
198 */
199 rb_define_const(mFiddle, "TYPE_SHORT", INT2NUM(TYPE_SHORT));
200
201 /* Document-const: TYPE_INT
202 *
203 * C type - int
204 */
205 rb_define_const(mFiddle, "TYPE_INT", INT2NUM(TYPE_INT));
206
207 /* Document-const: TYPE_LONG
208 *
209 * C type - long
210 */
211 rb_define_const(mFiddle, "TYPE_LONG", INT2NUM(TYPE_LONG));
212
213 #if HAVE_LONG_LONG
214 /* Document-const: TYPE_LONG_LONG
215 *
216 * C type - long long
217 */
218 rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
219 #endif
220
221 /* Document-const: TYPE_FLOAT
222 *
223 * C type - float
224 */
225 rb_define_const(mFiddle, "TYPE_FLOAT", INT2NUM(TYPE_FLOAT));
226
227 /* Document-const: TYPE_DOUBLE
228 *
229 * C type - double
230 */
231 rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
232
233 /* Document-const: TYPE_SIZE_T
234 *
235 * C type - size_t
236 */
237 rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T));
238
239 /* Document-const: TYPE_SSIZE_T
240 *
241 * C type - ssize_t
242 */
243 rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T));
244
245 /* Document-const: TYPE_PTRDIFF_T
246 *
247 * C type - ptrdiff_t
248 */
249 rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T));
250
251 /* Document-const: TYPE_INTPTR_T
252 *
253 * C type - intptr_t
254 */
255 rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T));
256
257 /* Document-const: TYPE_UINTPTR_T
258 *
259 * C type - uintptr_t
260 */
261 rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
262
263 /* Document-const: ALIGN_VOIDP
264 *
265 * The alignment size of a void*
266 */
267 rb_define_const(mFiddle, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
268
269 /* Document-const: ALIGN_CHAR
270 *
271 * The alignment size of a char
272 */
273 rb_define_const(mFiddle, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
274
275 /* Document-const: ALIGN_SHORT
276 *
277 * The alignment size of a short
278 */
279 rb_define_const(mFiddle, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
280
281 /* Document-const: ALIGN_INT
282 *
283 * The alignment size of an int
284 */
285 rb_define_const(mFiddle, "ALIGN_INT", INT2NUM(ALIGN_INT));
286
287 /* Document-const: ALIGN_LONG
288 *
289 * The alignment size of a long
290 */
291 rb_define_const(mFiddle, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
292
293 #if HAVE_LONG_LONG
294 /* Document-const: ALIGN_LONG_LONG
295 *
296 * The alignment size of a long long
297 */
298 rb_define_const(mFiddle, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
299 #endif
300
301 /* Document-const: ALIGN_FLOAT
302 *
303 * The alignment size of a float
304 */
305 rb_define_const(mFiddle, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
306
307 /* Document-const: ALIGN_DOUBLE
308 *
309 * The alignment size of a double
310 */
311 rb_define_const(mFiddle, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
312
313 /* Document-const: ALIGN_SIZE_T
314 *
315 * The alignment size of a size_t
316 */
317 rb_define_const(mFiddle, "ALIGN_SIZE_T", INT2NUM(ALIGN_OF(size_t)));
318
319 /* Document-const: ALIGN_SSIZE_T
320 *
321 * The alignment size of a ssize_t
322 */
323 rb_define_const(mFiddle, "ALIGN_SSIZE_T", INT2NUM(ALIGN_OF(size_t))); /* same as size_t */
324
325 /* Document-const: ALIGN_PTRDIFF_T
326 *
327 * The alignment size of a ptrdiff_t
328 */
329 rb_define_const(mFiddle, "ALIGN_PTRDIFF_T", INT2NUM(ALIGN_OF(ptrdiff_t)));
330
331 /* Document-const: ALIGN_INTPTR_T
332 *
333 * The alignment size of a intptr_t
334 */
335 rb_define_const(mFiddle, "ALIGN_INTPTR_T", INT2NUM(ALIGN_OF(intptr_t)));
336
337 /* Document-const: ALIGN_UINTPTR_T
338 *
339 * The alignment size of a uintptr_t
340 */
341 rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
342
343 /* Document-const: WINDOWS
344 *
345 * Returns a boolean regarding whether the host is WIN32
346 */
347 #if defined(_WIN32)
348 rb_define_const(mFiddle, "WINDOWS", Qtrue);
349 #else
350 rb_define_const(mFiddle, "WINDOWS", Qfalse);
351 #endif
352
353 /* Document-const: SIZEOF_VOIDP
354 *
355 * size of a void*
356 */
357 rb_define_const(mFiddle, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
358
359 /* Document-const: SIZEOF_CHAR
360 *
361 * size of a char
362 */
363 rb_define_const(mFiddle, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
364
365 /* Document-const: SIZEOF_SHORT
366 *
367 * size of a short
368 */
369 rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
370
371 /* Document-const: SIZEOF_INT
372 *
373 * size of an int
374 */
375 rb_define_const(mFiddle, "SIZEOF_INT", INT2NUM(sizeof(int)));
376
377 /* Document-const: SIZEOF_LONG
378 *
379 * size of a long
380 */
381 rb_define_const(mFiddle, "SIZEOF_LONG", INT2NUM(sizeof(long)));
382
383 #if HAVE_LONG_LONG
384 /* Document-const: SIZEOF_LONG_LONG
385 *
386 * size of a long long
387 */
388 rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
389 #endif
390
391 /* Document-const: SIZEOF_FLOAT
392 *
393 * size of a float
394 */
395 rb_define_const(mFiddle, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
396
397 /* Document-const: SIZEOF_DOUBLE
398 *
399 * size of a double
400 */
401 rb_define_const(mFiddle, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
402
403 /* Document-const: SIZEOF_SIZE_T
404 *
405 * size of a size_t
406 */
407 rb_define_const(mFiddle, "SIZEOF_SIZE_T", INT2NUM(sizeof(size_t)));
408
409 /* Document-const: SIZEOF_SSIZE_T
410 *
411 * size of a ssize_t
412 */
413 rb_define_const(mFiddle, "SIZEOF_SSIZE_T", INT2NUM(sizeof(size_t))); /* same as size_t */
414
415 /* Document-const: SIZEOF_PTRDIFF_T
416 *
417 * size of a ptrdiff_t
418 */
419 rb_define_const(mFiddle, "SIZEOF_PTRDIFF_T", INT2NUM(sizeof(ptrdiff_t)));
420
421 /* Document-const: SIZEOF_INTPTR_T
422 *
423 * size of a intptr_t
424 */
425 rb_define_const(mFiddle, "SIZEOF_INTPTR_T", INT2NUM(sizeof(intptr_t)));
426
427 /* Document-const: SIZEOF_UINTPTR_T
428 *
429 * size of a uintptr_t
430 */
431 rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
432
433 /* Document-const: RUBY_FREE
434 *
435 * Address of the ruby_xfree() function
436 */
437 rb_define_const(mFiddle, "RUBY_FREE", PTR2NUM(ruby_xfree));
438
439 /* Document-const: BUILD_RUBY_PLATFORM
440 *
441 * Platform built against (i.e. "x86_64-linux", etc.)
442 *
443 * See also RUBY_PLATFORM
444 */
445 rb_define_const(mFiddle, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
446
447 rb_define_module_function(mFiddle, "dlwrap", rb_fiddle_value2ptr, 1);
448 rb_define_module_function(mFiddle, "dlunwrap", rb_fiddle_ptr2value, 1);
449 rb_define_module_function(mFiddle, "malloc", rb_fiddle_malloc, 1);
450 rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
451 rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1);
452
453 Init_fiddle_function();
454 Init_fiddle_closure();
455 Init_fiddle_handle();
456 Init_fiddle_pointer();
457 }
458 /* vim: set noet sws=4 sw=4: */
459