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