Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
fiddle.c
Go to the documentation of this file.
1#include <fiddle.h>
2
6
7void Init_fiddle_pointer(void);
8void Init_fiddle_pinned(void);
9
10#ifdef FIDDLE_MEMORY_VIEW
11void Init_fiddle_memory_view(void);
12#endif
13
14/*
15 * call-seq: Fiddle.malloc(size)
16 *
17 * Allocate +size+ bytes of memory and return the integer memory address
18 * for the allocated memory.
19 */
20static VALUE
21rb_fiddle_malloc(VALUE self, VALUE size)
22{
23 void *ptr;
24 ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size));
25 return PTR2NUM(ptr);
26}
27
28/*
29 * call-seq: Fiddle.realloc(addr, size)
30 *
31 * Change the size of the memory allocated at the memory location +addr+ to
32 * +size+ bytes. Returns the memory address of the reallocated memory, which
33 * may be different than the address passed in.
34 */
35static VALUE
36rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
37{
38 void *ptr = NUM2PTR(addr);
39
41 return PTR2NUM(ptr);
42}
43
44/*
45 * call-seq: Fiddle.free(addr)
46 *
47 * Free the memory at address +addr+
48 */
51{
52 void *ptr = NUM2PTR(addr);
53
55 return Qnil;
56}
57
58/*
59 * call-seq: Fiddle.dlunwrap(addr)
60 *
61 * Returns the hexadecimal representation of a memory pointer address +addr+
62 *
63 * Example:
64 *
65 * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
66 * => #<Fiddle::Handle:0x00000001342460>
67 *
68 * lib['strcpy'].to_s(16)
69 * => "7f59de6dd240"
70 *
71 * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
72 * => "7f59de6dd240"
73 */
76{
77 return (VALUE)NUM2PTR(addr);
78}
79
80/*
81 * call-seq: Fiddle.dlwrap(val)
82 *
83 * Returns a memory pointer of a function's hexadecimal address location +val+
84 *
85 * Example:
86 *
87 * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
88 * => #<Fiddle::Handle:0x00000001342460>
89 *
90 * Fiddle.dlwrap(lib['strcpy'].to_s(16))
91 * => 25522520
92 */
93static VALUE
94rb_fiddle_value2ptr(VALUE self, VALUE val)
95{
96 return PTR2NUM((void*)val);
97}
98
99void Init_fiddle_handle(void);
100
101void
103{
104 /*
105 * Document-module: Fiddle
106 *
107 * A libffi wrapper for Ruby.
108 *
109 * == Description
110 *
111 * Fiddle is an extension to translate a foreign function interface (FFI)
112 * with ruby.
113 *
114 * It wraps {libffi}[http://sourceware.org/libffi/], a popular C library
115 * which provides a portable interface that allows code written in one
116 * language to call code written in another language.
117 *
118 * == Example
119 *
120 * Here we will use Fiddle::Function to wrap {floor(3) from
121 * libm}[http://linux.die.net/man/3/floor]
122 *
123 * require 'fiddle'
124 *
125 * libm = Fiddle.dlopen('/lib/libm.so.6')
126 *
127 * floor = Fiddle::Function.new(
128 * libm['floor'],
129 * [Fiddle::TYPE_DOUBLE],
130 * Fiddle::TYPE_DOUBLE
131 * )
132 *
133 * puts floor.call(3.14159) #=> 3.0
134 *
135 *
136 */
137 mFiddle = rb_define_module("Fiddle");
138
139 /*
140 * Document-class: Fiddle::Error
141 *
142 * Generic error class for Fiddle
143 */
145
146 /*
147 * Ruby installed by RubyInstaller for Windows always require
148 * bundled Fiddle because ruby_installer/runtime/dll_directory.rb
149 * requires Fiddle. It's used by
150 * rubygems/defaults/operating_system.rb. It means that the
151 * bundled Fiddle is always required on initialization.
152 *
153 * We just remove existing Fiddle::DLError here to override
154 * the bundled Fiddle.
155 */
156 if (rb_const_defined(mFiddle, rb_intern("DLError"))) {
157 rb_const_remove(mFiddle, rb_intern("DLError"));
158 }
159
160 /*
161 * Document-class: Fiddle::DLError
162 *
163 * standard dynamic load exception
164 */
166
167 /* Document-const: TYPE_VOID
168 *
169 * C type - void
170 */
172
173 /* Document-const: TYPE_VOIDP
174 *
175 * C type - void*
176 */
177 rb_define_const(mFiddle, "TYPE_VOIDP", INT2NUM(TYPE_VOIDP));
178
179 /* Document-const: TYPE_CHAR
180 *
181 * C type - char
182 */
184
185 /* Document-const: TYPE_SHORT
186 *
187 * C type - short
188 */
189 rb_define_const(mFiddle, "TYPE_SHORT", INT2NUM(TYPE_SHORT));
190
191 /* Document-const: TYPE_INT
192 *
193 * C type - int
194 */
196
197 /* Document-const: TYPE_LONG
198 *
199 * C type - long
200 */
202
203#if HAVE_LONG_LONG
204 /* Document-const: TYPE_LONG_LONG
205 *
206 * C type - long long
207 */
208 rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
209#endif
210
211#ifdef TYPE_INT8_T
212 /* Document-const: TYPE_INT8_T
213 *
214 * C type - int8_t
215 */
216 rb_define_const(mFiddle, "TYPE_INT8_T", INT2NUM(TYPE_INT8_T));
217#endif
218
219#ifdef TYPE_INT16_T
220 /* Document-const: TYPE_INT16_T
221 *
222 * C type - int16_t
223 */
224 rb_define_const(mFiddle, "TYPE_INT16_T", INT2NUM(TYPE_INT16_T));
225#endif
226
227#ifdef TYPE_INT32_T
228 /* Document-const: TYPE_INT32_T
229 *
230 * C type - int32_t
231 */
232 rb_define_const(mFiddle, "TYPE_INT32_T", INT2NUM(TYPE_INT32_T));
233#endif
234
235#ifdef TYPE_INT64_T
236 /* Document-const: TYPE_INT64_T
237 *
238 * C type - int64_t
239 */
240 rb_define_const(mFiddle, "TYPE_INT64_T", INT2NUM(TYPE_INT64_T));
241#endif
242
243 /* Document-const: TYPE_FLOAT
244 *
245 * C type - float
246 */
247 rb_define_const(mFiddle, "TYPE_FLOAT", INT2NUM(TYPE_FLOAT));
248
249 /* Document-const: TYPE_DOUBLE
250 *
251 * C type - double
252 */
253 rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
254
255#ifdef HAVE_FFI_PREP_CIF_VAR
256 /* Document-const: TYPE_VARIADIC
257 *
258 * C type - ...
259 */
260 rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC));
261#endif
262
263 /* Document-const: TYPE_CONST_STRING
264 *
265 * C type - const char* ('\0' terminated const char*)
266 */
267 rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING));
268
269 /* Document-const: TYPE_SIZE_T
270 *
271 * C type - size_t
272 */
273 rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T));
274
275 /* Document-const: TYPE_SSIZE_T
276 *
277 * C type - ssize_t
278 */
279 rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T));
280
281 /* Document-const: TYPE_PTRDIFF_T
282 *
283 * C type - ptrdiff_t
284 */
285 rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T));
286
287 /* Document-const: TYPE_INTPTR_T
288 *
289 * C type - intptr_t
290 */
291 rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T));
292
293 /* Document-const: TYPE_UINTPTR_T
294 *
295 * C type - uintptr_t
296 */
297 rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
298
299 /* Document-const: ALIGN_VOIDP
300 *
301 * The alignment size of a void*
302 */
303 rb_define_const(mFiddle, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
304
305 /* Document-const: ALIGN_CHAR
306 *
307 * The alignment size of a char
308 */
309 rb_define_const(mFiddle, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
310
311 /* Document-const: ALIGN_SHORT
312 *
313 * The alignment size of a short
314 */
315 rb_define_const(mFiddle, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
316
317 /* Document-const: ALIGN_INT
318 *
319 * The alignment size of an int
320 */
322
323 /* Document-const: ALIGN_LONG
324 *
325 * The alignment size of a long
326 */
327 rb_define_const(mFiddle, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
328
329#if HAVE_LONG_LONG
330 /* Document-const: ALIGN_LONG_LONG
331 *
332 * The alignment size of a long long
333 */
334 rb_define_const(mFiddle, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
335#endif
336
337 /* Document-const: ALIGN_INT8_T
338 *
339 * The alignment size of a int8_t
340 */
341 rb_define_const(mFiddle, "ALIGN_INT8_T", INT2NUM(ALIGN_INT8_T));
342
343 /* Document-const: ALIGN_INT16_T
344 *
345 * The alignment size of a int16_t
346 */
347 rb_define_const(mFiddle, "ALIGN_INT16_T", INT2NUM(ALIGN_INT16_T));
348
349 /* Document-const: ALIGN_INT32_T
350 *
351 * The alignment size of a int32_t
352 */
353 rb_define_const(mFiddle, "ALIGN_INT32_T", INT2NUM(ALIGN_INT32_T));
354
355 /* Document-const: ALIGN_INT64_T
356 *
357 * The alignment size of a int64_t
358 */
359 rb_define_const(mFiddle, "ALIGN_INT64_T", INT2NUM(ALIGN_INT64_T));
360
361 /* Document-const: ALIGN_FLOAT
362 *
363 * The alignment size of a float
364 */
365 rb_define_const(mFiddle, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
366
367 /* Document-const: ALIGN_DOUBLE
368 *
369 * The alignment size of a double
370 */
372
373 /* Document-const: ALIGN_SIZE_T
374 *
375 * The alignment size of a size_t
376 */
377 rb_define_const(mFiddle, "ALIGN_SIZE_T", INT2NUM(ALIGN_OF(size_t)));
378
379 /* Document-const: ALIGN_SSIZE_T
380 *
381 * The alignment size of a ssize_t
382 */
383 rb_define_const(mFiddle, "ALIGN_SSIZE_T", INT2NUM(ALIGN_OF(size_t))); /* same as size_t */
384
385 /* Document-const: ALIGN_PTRDIFF_T
386 *
387 * The alignment size of a ptrdiff_t
388 */
389 rb_define_const(mFiddle, "ALIGN_PTRDIFF_T", INT2NUM(ALIGN_OF(ptrdiff_t)));
390
391 /* Document-const: ALIGN_INTPTR_T
392 *
393 * The alignment size of a intptr_t
394 */
395 rb_define_const(mFiddle, "ALIGN_INTPTR_T", INT2NUM(ALIGN_OF(intptr_t)));
396
397 /* Document-const: ALIGN_UINTPTR_T
398 *
399 * The alignment size of a uintptr_t
400 */
401 rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
402
403 /* Document-const: WINDOWS
404 *
405 * Returns a boolean regarding whether the host is WIN32
406 */
407#if defined(_WIN32)
408 rb_define_const(mFiddle, "WINDOWS", Qtrue);
409#else
410 rb_define_const(mFiddle, "WINDOWS", Qfalse);
411#endif
412
413 /* Document-const: SIZEOF_VOIDP
414 *
415 * size of a void*
416 */
417 rb_define_const(mFiddle, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
418
419 /* Document-const: SIZEOF_CHAR
420 *
421 * size of a char
422 */
423 rb_define_const(mFiddle, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
424
425 /* Document-const: SIZEOF_SHORT
426 *
427 * size of a short
428 */
429 rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
430
431 /* Document-const: SIZEOF_INT
432 *
433 * size of an int
434 */
435 rb_define_const(mFiddle, "SIZEOF_INT", INT2NUM(sizeof(int)));
436
437 /* Document-const: SIZEOF_LONG
438 *
439 * size of a long
440 */
441 rb_define_const(mFiddle, "SIZEOF_LONG", INT2NUM(sizeof(long)));
442
443#if HAVE_LONG_LONG
444 /* Document-const: SIZEOF_LONG_LONG
445 *
446 * size of a long long
447 */
448 rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
449#endif
450
451 /* Document-const: SIZEOF_INT8_T
452 *
453 * size of a int8_t
454 */
455 rb_define_const(mFiddle, "SIZEOF_INT8_T", INT2NUM(sizeof(int8_t)));
456
457 /* Document-const: SIZEOF_INT16_T
458 *
459 * size of a int16_t
460 */
461 rb_define_const(mFiddle, "SIZEOF_INT16_T", INT2NUM(sizeof(int16_t)));
462
463 /* Document-const: SIZEOF_INT32_T
464 *
465 * size of a int32_t
466 */
467 rb_define_const(mFiddle, "SIZEOF_INT32_T", INT2NUM(sizeof(int32_t)));
468
469 /* Document-const: SIZEOF_INT64_T
470 *
471 * size of a int64_t
472 */
473 rb_define_const(mFiddle, "SIZEOF_INT64_T", INT2NUM(sizeof(int64_t)));
474
475 /* Document-const: SIZEOF_FLOAT
476 *
477 * size of a float
478 */
479 rb_define_const(mFiddle, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
480
481 /* Document-const: SIZEOF_DOUBLE
482 *
483 * size of a double
484 */
485 rb_define_const(mFiddle, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
486
487 /* Document-const: SIZEOF_SIZE_T
488 *
489 * size of a size_t
490 */
491 rb_define_const(mFiddle, "SIZEOF_SIZE_T", INT2NUM(sizeof(size_t)));
492
493 /* Document-const: SIZEOF_SSIZE_T
494 *
495 * size of a ssize_t
496 */
497 rb_define_const(mFiddle, "SIZEOF_SSIZE_T", INT2NUM(sizeof(size_t))); /* same as size_t */
498
499 /* Document-const: SIZEOF_PTRDIFF_T
500 *
501 * size of a ptrdiff_t
502 */
503 rb_define_const(mFiddle, "SIZEOF_PTRDIFF_T", INT2NUM(sizeof(ptrdiff_t)));
504
505 /* Document-const: SIZEOF_INTPTR_T
506 *
507 * size of a intptr_t
508 */
509 rb_define_const(mFiddle, "SIZEOF_INTPTR_T", INT2NUM(sizeof(intptr_t)));
510
511 /* Document-const: SIZEOF_UINTPTR_T
512 *
513 * size of a uintptr_t
514 */
515 rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
516
517 /* Document-const: SIZEOF_CONST_STRING
518 *
519 * size of a const char*
520 */
521 rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
522
523 /* Document-const: RUBY_FREE
524 *
525 * Address of the ruby_xfree() function
526 */
528
529 /* Document-const: BUILD_RUBY_PLATFORM
530 *
531 * Platform built against (i.e. "x86_64-linux", etc.)
532 *
533 * See also RUBY_PLATFORM
534 */
535 rb_define_const(mFiddle, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
536
537 rb_define_module_function(mFiddle, "dlwrap", rb_fiddle_value2ptr, 1);
539 rb_define_module_function(mFiddle, "malloc", rb_fiddle_malloc, 1);
540 rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
542
548
549#ifdef FIDDLE_MEMORY_VIEW
550 Init_fiddle_memory_view();
551#endif
552}
553/* vim: set noet sws=4 sw=4: */
void Init_fiddle_closure(void)
Definition: closure.c:307
#define NUM2PTR(x)
Definition: conversions.h:46
#define PTR2NUM(x)
Definition: conversions.h:45
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
Definition: cxxanyargs.hpp:672
struct RIMemo * ptr
Definition: debug.c:88
void Init_fiddle(void)
Definition: fiddle.c:102
void Init_fiddle_pointer(void)
Definition: pointer.c:794
VALUE mFiddle
Definition: fiddle.c:3
VALUE rb_eFiddleDLError
Definition: fiddle.c:4
VALUE rb_fiddle_ptr2value(VALUE self, VALUE addr)
Definition: fiddle.c:75
VALUE rb_fiddle_free(VALUE self, VALUE addr)
Definition: fiddle.c:50
void Init_fiddle_pinned(void)
Definition: pinned.c:108
VALUE rb_eFiddleError
Definition: fiddle.c:5
void Init_fiddle_handle(void)
Definition: handle.c:376
#define TYPE_VARIADIC
Definition: fiddle.h:118
#define TYPE_CONST_STRING
Definition: fiddle.h:119
#define TYPE_FLOAT
Definition: fiddle.h:116
#define TYPE_PTRDIFF_T
Definition: fiddle.h:155
#define TYPE_CHAR
Definition: fiddle.h:109
#define ALIGN_INT16_T
Definition: fiddle.h:188
#define TYPE_VOID
Definition: fiddle.h:107
#define ALIGN_INT8_T
Definition: fiddle.h:187
#define ALIGN_DOUBLE
Definition: fiddle.h:185
#define TYPE_INT
Definition: fiddle.h:111
#define ALIGN_INT32_T
Definition: fiddle.h:189
#define TYPE_LONG
Definition: fiddle.h:112
#define TYPE_SIZE_T
Definition: fiddle.h:151
#define ALIGN_INT64_T
Definition: fiddle.h:190
#define ALIGN_OF(type)
Definition: fiddle.h:174
#define ALIGN_CHAR
Definition: fiddle.h:177
#define ALIGN_LONG
Definition: fiddle.h:180
#define TYPE_VOIDP
Definition: fiddle.h:108
#define TYPE_INTPTR_T
Definition: fiddle.h:165
#define ALIGN_SHORT
Definition: fiddle.h:178
#define TYPE_SSIZE_T
Definition: fiddle.h:144
#define ALIGN_FLOAT
Definition: fiddle.h:184
#define TYPE_DOUBLE
Definition: fiddle.h:117
#define TYPE_SHORT
Definition: fiddle.h:110
#define TYPE_UINTPTR_T
Definition: fiddle.h:172
#define ALIGN_VOIDP
Definition: fiddle.h:176
#define ALIGN_INT
Definition: fiddle.h:179
#define TYPE_INT8_T
Definition: fiddle.h:121
void Init_fiddle_function(void)
Definition: function.c:396
void ruby_xfree(void *x)
Deallocates a storage instance.
Definition: gc.c:10914
void * ruby_xcalloc(size_t n, size_t size)
Identical to ruby_xmalloc2(), except it zero-fills the region before it returns.
Definition: gc.c:12815
void * ruby_xrealloc(void *ptr, size_t new_size)
Resize the storage instance.
Definition: gc.c:12825
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:797
VALUE rb_define_module(const char *name)
Definition: class.c:871
VALUE rb_eStandardError
Definition: error.c:1054
#define RUBY_PLATFORM
Definition: config.h:98
#define rb_str_new2
Definition: string.h:276
VALUE rb_const_remove(VALUE, ID)
Definition: variable.c:2727
int rb_const_defined(VALUE, ID)
Definition: variable.c:2928
ID rb_intern(const char *)
Definition: symbol.c:785
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:3150
#define INT2NUM
Definition: int.h:43
voidpf void uLong size
Definition: ioapi.h:138
#define NUM2SIZET
Definition: size_t.h:51
#define Qtrue
#define Qnil
#define Qfalse
unsigned long VALUE
Definition: value.h:38
int intptr_t
Definition: win32.h:90
unsigned int uintptr_t
Definition: win32.h:106