Ruby  2.0.0p247(2013-06-27revision41674)
fiddle.c
Go to the documentation of this file.
1 #include <fiddle.h>
2 
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
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
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
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
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
126 {
127  return PTR2NUM((void*)val);
128 }
129 
130 void Init_fiddle_handle(void);
131 
132 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  */
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 
452 
457 }
458 /* vim: set noet sws=4 sw=4: */
VALUE rb_eStandardError
Definition: error.c:509
#define TYPE_VOIDP
Definition: fiddle.h:113
VALUE mFiddle
Definition: fiddle.c:3
static VALUE rb_fiddle_value2ptr(VALUE self, VALUE val)
Definition: fiddle.c:125
void rb_secure(int)
Definition: safe.c:79
#define NUM2PTR(x)
Definition: dl.h:169
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
#define TYPE_CHAR
Definition: fiddle.h:114
#define ALIGN_FLOAT
Definition: dl.h:147
return Qtrue
Definition: tcltklib.c:9610
#define rb_str_new2
#define TYPE_SHORT
Definition: fiddle.h:115
static VALUE rb_fiddle_malloc(VALUE self, VALUE size)
Definition: fiddle.c:47
#define ALIGN_OF(type)
Definition: dl.h:137
VALUE rb_eFiddleError
Definition: fiddle.c:4
#define ALIGN_VOIDP
Definition: dl.h:139
#define TYPE_UINTPTR_T
Definition: fiddle.c:36
void Init_fiddle_handle(void)
Definition: handle.c:368
#define TYPE_INT
Definition: fiddle.h:116
#define TYPE_DOUBLE
Definition: fiddle.h:122
return Qfalse
Definition: tcltklib.c:6779
#define TYPE_LONG
Definition: fiddle.h:117
#define Qnil
Definition: tcltklib.c:1896
#define val
Definition: tcltklib.c:1949
void Init_fiddle_pointer(void)
Definition: pointer.c:673
#define ALIGN_LONG
Definition: dl.h:143
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2197
#define PTR2NUM(x)
Definition: dl.h:168
#define ALIGN_CHAR
Definition: dl.h:141
static VALUE rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
Definition: fiddle.c:64
#define TYPE_SIZE_T
Definition: fiddle.c:15
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1508
void Init_fiddle(void)
Definition: fiddle.c:133
void ruby_xfree(void *x)
Definition: gc.c:3649
#define ALIGN_SHORT
Definition: dl.h:140
unsigned int uintptr_t
Definition: win32.h:94
VALUE rb_fiddle_ptr2value(VALUE self, VALUE addr)
Definition: fiddle.c:105
#define TYPE_SSIZE_T
Definition: fiddle.c:8
int intptr_t
Definition: win32.h:86
return ptr
Definition: tcltklib.c:784
#define TYPE_FLOAT
Definition: fiddle.h:121
void * ruby_xmalloc(size_t size)
Definition: gc.c:3592
#define ALIGN_DOUBLE
Definition: dl.h:148
void * ruby_xrealloc(void *ptr, size_t size)
Definition: gc.c:3633
#define RUBY_PLATFORM
Definition: defines.h:237
int size
Definition: encoding.c:52
#define TYPE_VOID
Definition: fiddle.h:112
#define INT2NUM(x)
void Init_fiddle_closure()
Definition: closure.c:257
#define NUM2INT(x)
unsigned long VALUE
Definition: ripper.y:104
VALUE rb_define_module(const char *name)
Definition: class.c:617
#define TYPE_PTRDIFF_T
Definition: fiddle.c:19
void Init_fiddle_function(void)
Definition: function.c:173
VALUE rb_fiddle_free(VALUE self, VALUE addr)
Definition: fiddle.c:79
#define ALIGN_INT
Definition: dl.h:142
#define TYPE_INTPTR_T
Definition: fiddle.c:29