Ruby  1.9.3p547(2014-05-14revision45962)
dl.c
Go to the documentation of this file.
1 /*
2  * ext/dl/dl.c
3  *
4  * doumentation:
5  * - Vincent Batts (vbatts@hashbangbash.com)
6  *
7  */
8 #include <ruby/ruby.h>
9 #include <ruby/io.h>
10 #include <ctype.h>
11 #include "dl.h"
12 
16 
19 
20 VALUE
22 {
23  return rb_class_new_instance(argc, argv, rb_cDLHandle);
24 }
25 
26 /*
27  * call-seq: DL.malloc
28  *
29  * Allocate +size+ bytes of memory and return the integer memory address
30  * for the allocated memory.
31  */
32 VALUE
34 {
35  void *ptr;
36 
37  rb_secure(4);
38  ptr = (void*)ruby_xmalloc(NUM2INT(size));
39  return PTR2NUM(ptr);
40 }
41 
42 /*
43  * call-seq: DL.realloc(addr, size)
44  *
45  * Change the size of the memory allocated at the memory location +addr+ to
46  * +size+ bytes. Returns the memory address of the reallocated memory, which
47  * may be different than the address passed in.
48  */
49 VALUE
51 {
52  void *ptr = NUM2PTR(addr);
53 
54  rb_secure(4);
55  ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
56  return PTR2NUM(ptr);
57 }
58 
59 /*
60  * call-seq: DL.free(addr)
61  *
62  * Free the memory at address +addr+
63  */
64 VALUE
65 rb_dl_free(VALUE self, VALUE addr)
66 {
67  void *ptr = NUM2PTR(addr);
68 
69  rb_secure(4);
70  ruby_xfree(ptr);
71  return Qnil;
72 }
73 
74 VALUE
76 {
77  rb_secure(4);
78  return (VALUE)NUM2PTR(addr);
79 }
80 
81 VALUE
83 {
84  return PTR2NUM((void*)val);
85 }
86 
87 static void
89 {
90  static const char cb[] = "dl/callback.so";
91 
92  rb_autoload(dl, rb_intern_const("CdeclCallbackAddrs"), cb);
93  rb_autoload(dl, rb_intern_const("CdeclCallbackProcs"), cb);
94 #ifdef FUNC_STDCALL
95  rb_autoload(dl, rb_intern_const("StdcallCallbackAddrs"), cb);
96  rb_autoload(dl, rb_intern_const("StdcallCallbackProcs"), cb);
97 #endif
98 }
99 
100 void
101 Init_dl(void)
102 {
103  void Init_dlhandle(void);
104  void Init_dlcfunc(void);
105  void Init_dlptr(void);
106 
107  rbdl_id_cdecl = rb_intern_const("cdecl");
108  rbdl_id_stdcall = rb_intern_const("stdcall");
109 
110  /* Document-module: DL
111  *
112  * A bridge to the dlopen() or dynamic library linker function.
113  *
114  * == Example
115  *
116  * bash $> cat > sum.c <<EOF
117  * double sum(double *arry, int len)
118  * {
119  * double ret = 0;
120  * int i;
121  * for(i = 0; i < len; i++){
122  * ret = ret + arry[i];
123  * }
124  * return ret;
125  * }
126  *
127  * double split(double num)
128  * {
129  * double ret = 0;
130  * ret = num / 2;
131  * return ret;
132  * }
133  * EOF
134  * bash $> gcc -o libsum.so -shared sum.c
135  * bash $> cat > sum.rb <<EOF
136  * require 'dl'
137  * require 'dl/import'
138  *
139  * module LibSum
140  * extend DL::Importer
141  * dlload './libsum.so'
142  * extern 'double sum(double*, int)'
143  * extern 'double split(double)'
144  * end
145  *
146  * a = [2.0, 3.0, 4.0]
147  *
148  * sum = LibSum.sum(a.pack("d*"), a.count)
149  * p LibSum.split(sum)
150  * EOF
151  * bash $> ruby sum.rb
152  * 4.5
153  *
154  * WIN! :-)
155  */
156  rb_mDL = rb_define_module("DL");
157 
158  /*
159  * Document-class: DL::DLError
160  *
161  * standard dynamic load exception
162  */
164 
165  /*
166  * Document-class: DL::DLTypeError
167  *
168  * dynamic load incorrect type exception
169  */
171 
172  /* Document-const: MAX_CALLBACK
173  *
174  * Maximum number of callbacks
175  */
176  rb_define_const(rb_mDL, "MAX_CALLBACK", INT2NUM(MAX_CALLBACK));
177 
178  /* Document-const: DLSTACK_SIZE
179  *
180  * Dynamic linker stack size
181  */
182  rb_define_const(rb_mDL, "DLSTACK_SIZE", INT2NUM(DLSTACK_SIZE));
183 
185 
186  /* Document-const: RTLD_GLOBAL
187  *
188  * rtld DL::Handle flag.
189  *
190  * The symbols defined by this library will be made available for symbol
191  * resolution of subsequently loaded libraries.
192  */
193  rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL));
194 
195  /* Document-const: RTLD_LAZY
196  *
197  * rtld DL::Handle flag.
198  *
199  * Perform lazy binding. Only resolve symbols as the code that references
200  * them is executed. If the symbol is never referenced, then it is never
201  * resolved. (Lazy binding is only performed for function references;
202  * references to variables are always immediately bound when the library
203  * is loaded.)
204  */
205  rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY));
206 
207  /* Document-const: RTLD_NOW
208  *
209  * rtld DL::Handle flag.
210  *
211  * If this value is specified or the environment variable LD_BIND_NOW is
212  * set to a nonempty string, all undefined symbols in the library are
213  * resolved before dlopen() returns. If this cannot be done an error is
214  * returned.
215  */
216  rb_define_const(rb_mDL, "RTLD_NOW", INT2NUM(RTLD_NOW));
217 
218  /* Document-const: TYPE_VOID
219  *
220  * DL::CFunc type - void
221  */
222  rb_define_const(rb_mDL, "TYPE_VOID", INT2NUM(DLTYPE_VOID));
223 
224  /* Document-const: TYPE_VOIDP
225  *
226  * DL::CFunc type - void*
227  */
228  rb_define_const(rb_mDL, "TYPE_VOIDP", INT2NUM(DLTYPE_VOIDP));
229 
230  /* Document-const: TYPE_CHAR
231  *
232  * DL::CFunc type - char
233  */
234  rb_define_const(rb_mDL, "TYPE_CHAR", INT2NUM(DLTYPE_CHAR));
235 
236  /* Document-const: TYPE_SHORT
237  *
238  * DL::CFunc type - short
239  */
240  rb_define_const(rb_mDL, "TYPE_SHORT", INT2NUM(DLTYPE_SHORT));
241 
242  /* Document-const: TYPE_INT
243  *
244  * DL::CFunc type - int
245  */
246  rb_define_const(rb_mDL, "TYPE_INT", INT2NUM(DLTYPE_INT));
247 
248  /* Document-const: TYPE_LONG
249  *
250  * DL::CFunc type - long
251  */
252  rb_define_const(rb_mDL, "TYPE_LONG", INT2NUM(DLTYPE_LONG));
253 
254 #if HAVE_LONG_LONG
255  /* Document-const: TYPE_LONG_LONG
256  *
257  * DL::CFunc type - long long
258  */
259  rb_define_const(rb_mDL, "TYPE_LONG_LONG", INT2NUM(DLTYPE_LONG_LONG));
260 #endif
261 
262  /* Document-const: TYPE_FLOAT
263  *
264  * DL::CFunc type - float
265  */
266  rb_define_const(rb_mDL, "TYPE_FLOAT", INT2NUM(DLTYPE_FLOAT));
267 
268  /* Document-const: TYPE_DOUBLE
269  *
270  * DL::CFunc type - double
271  */
272  rb_define_const(rb_mDL, "TYPE_DOUBLE", INT2NUM(DLTYPE_DOUBLE));
273 
274  /* Document-const: ALIGN_VOIDP
275  *
276  * The Offset of a struct void* and a void*
277  */
278  rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
279 
280  /* Document-const: ALIGN_CHAR
281  *
282  * The Offset of a struct char and a char
283  */
284  rb_define_const(rb_mDL, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
285 
286  /* Document-const: ALIGN_SHORT
287  *
288  * The Offset of a struct short and a short
289  */
290  rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
291 
292  /* Document-const: ALIGN_INT
293  *
294  * The Offset of a struct int and a int
295  */
296  rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT));
297 
298  /* Document-const: ALIGN_LONG
299  *
300  * The Offset of a struct long and a long
301  */
302  rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
303 
304 #if HAVE_LONG_LONG
305  /* Document-const: ALIGN_LONG_LONG
306  *
307  * The Offset of a struct long long and a long long
308  */
309  rb_define_const(rb_mDL, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
310 #endif
311 
312  /* Document-const: ALIGN_FLOAT
313  *
314  * The Offset of a struct float and a float
315  */
316  rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
317 
318  /* Document-const: ALIGN_DOUBLE
319  *
320  * The Offset of a struct double and a double
321  */
322  rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
323 
324  /* Document-const: SIZEOF_VOIDP
325  *
326  * OS Dependent - sizeof(void*)
327  */
328  rb_define_const(rb_mDL, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
329 
330  /* Document-const: SIZEOF_CHAR
331  *
332  * OS Dependent - sizeof(char)
333  */
334  rb_define_const(rb_mDL, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
335 
336  /* Document-const: SIZEOF_SHORT
337  *
338  * OS Dependent - sizeof(short)
339  */
340  rb_define_const(rb_mDL, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
341 
342  /* Document-const: SIZEOF_INT
343  *
344  * OS Dependent - sizeof(int)
345  */
346  rb_define_const(rb_mDL, "SIZEOF_INT", INT2NUM(sizeof(int)));
347 
348  /* Document-const: SIZEOF_LONG
349  *
350  * OS Dependent - sizeof(long)
351  */
352  rb_define_const(rb_mDL, "SIZEOF_LONG", INT2NUM(sizeof(long)));
353 
354 #if HAVE_LONG_LONG
355  /* Document-const: SIZEOF_LONG_LONG
356  *
357  * OS Dependent - sizeof(long long)
358  */
359  rb_define_const(rb_mDL, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
360 #endif
361 
362  /* Document-const: SIZEOF_FLOAT
363  *
364  * OS Dependent - sizeof(float)
365  */
366  rb_define_const(rb_mDL, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
367 
368  /* Document-const: SIZEOF_DOUBLE
369  *
370  * OS Dependent - sizeof(double)
371  */
372  rb_define_const(rb_mDL, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
373 
376 
381 
382  /* Document-const: RUBY_FREE
383  *
384  * Address of the ruby_xfree() function
385  */
386  rb_define_const(rb_mDL, "RUBY_FREE", PTR2NUM(ruby_xfree));
387 
388  /* Document-const: BUILD_RUBY_PLATFORM
389  *
390  * Platform built against (i.e. "x86_64-linux", etc.)
391  *
392  * See also RUBY_PLATFORM
393  */
394  rb_define_const(rb_mDL, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
395 
396  /* Document-const: BUILD_RUBY_VERSION
397  *
398  * Ruby Version built. (i.e. "1.9.3")
399  *
400  * See also RUBY_VERSION
401  */
402  rb_define_const(rb_mDL, "BUILD_RUBY_VERSION", rb_str_new2(RUBY_VERSION));
403 
404  Init_dlhandle();
405  Init_dlcfunc();
406  Init_dlptr();
407 }
ID rbdl_id_stdcall
Definition: dl.c:18
VALUE rb_eStandardError
Definition: error.c:465
VALUE rb_mDL
Definition: dl.c:13
#define NUM2INT(x)
Definition: ruby.h:536
#define DLTYPE_SHORT
Definition: dl.h:166
static void rb_dl_init_callbacks(VALUE dl)
Definition: dl.c:88
ID rbdl_id_cdecl
Definition: dl.c:17
void rb_autoload(VALUE, ID, const char *)
Definition: variable.c:1438
#define RUBY_VERSION
Definition: tcltklib.c:16
static VALUE INT2NUM(int v)
Definition: ruby.h:981
#define NUM2PTR(x)
Definition: dl.h:178
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:515
VALUE rb_dl_realloc(VALUE self, VALUE addr, VALUE size)
Definition: dl.c:50
#define ALIGN_FLOAT
Definition: dl.h:155
VALUE rb_eDLError
Definition: dl.c:14
#define DLTYPE_VOID
Definition: dl.h:163
VALUE rb_eDLTypeError
Definition: dl.c:15
VALUE rb_dl_ptr2value(VALUE self, VALUE addr)
Definition: dl.c:75
#define ALIGN_VOIDP
Definition: dl.h:147
void Init_dl(void)
Definition: dl.c:101
#define MAX_CALLBACK
Definition: dl.h:34
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1639
#define DLTYPE_DOUBLE
Definition: dl.h:173
VALUE rb_dl_malloc(VALUE self, VALUE size)
Definition: dl.c:33
#define ALIGN_LONG
Definition: dl.h:151
#define PTR2NUM(x)
Definition: dl.h:177
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:1923
int argc
Definition: ruby.c:120
#define ALIGN_CHAR
Definition: dl.h:149
void * ptr
Definition: dl.h:210
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1358
VALUE rb_dl_free(VALUE self, VALUE addr)
Definition: dl.c:65
void ruby_xfree(void *x)
Definition: gc.c:916
#define ALIGN_SHORT
Definition: dl.h:148
unsigned long ID
Definition: ruby.h:89
#define Qnil
Definition: ruby.h:367
unsigned long VALUE
Definition: ruby.h:88
void Init_dlhandle(void)
Definition: handle.c:362
VALUE rb_dl_value2ptr(VALUE self, VALUE val)
Definition: dl.c:82
void * ruby_xmalloc(size_t size)
Definition: gc.c:859
#define ALIGN_DOUBLE
Definition: dl.h:156
void * ruby_xrealloc(void *ptr, size_t size)
Definition: gc.c:900
#define RUBY_PLATFORM
Definition: defines.h:307
int size
Definition: encoding.c:51
#define DLTYPE_INT
Definition: dl.h:167
#define DLTYPE_FLOAT
Definition: dl.h:172
#define DLTYPE_VOIDP
Definition: dl.h:164
void Init_dlptr(void)
Definition: cptr.c:646
#define DLTYPE_LONG
Definition: dl.h:168
#define DLTYPE_CHAR
Definition: dl.h:165
VALUE rb_cDLHandle
Definition: handle.c:8
void rb_secure(int)
Definition: safe.c:79
#define rb_intern_const(str)
Definition: ruby.h:1141
VALUE rb_define_module(const char *name)
Definition: class.c:587
VALUE rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
Definition: dl.c:21
#define ALIGN_INT
Definition: dl.h:150
void Init_dlcfunc(void)
Definition: cfunc.c:621
VALUE rb_str_new2(const char *)
#define DLSTACK_SIZE
Definition: dl.h:36
char ** argv
Definition: ruby.c:121