Ruby
1.9.3p551(2014-11-13revision48407)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
dl
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
13
VALUE
rb_mDL
;
14
VALUE
rb_eDLError
;
15
VALUE
rb_eDLTypeError
;
16
17
ID
rbdl_id_cdecl
;
18
ID
rbdl_id_stdcall
;
19
20
VALUE
21
rb_dl_dlopen
(
int
argc
,
VALUE
argv
[],
VALUE
self
)
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
33
rb_dl_malloc
(
VALUE
self
,
VALUE
size
)
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
50
rb_dl_realloc
(
VALUE
self
,
VALUE
addr,
VALUE
size
)
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
75
rb_dl_ptr2value
(
VALUE
self
,
VALUE
addr)
76
{
77
rb_secure
(4);
78
return
(
VALUE
)
NUM2PTR
(addr);
79
}
80
81
VALUE
82
rb_dl_value2ptr
(
VALUE
self
,
VALUE
val)
83
{
84
return
PTR2NUM
((
void
*)val);
85
}
86
87
static
void
88
rb_dl_init_callbacks
(
VALUE
dl)
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
*/
163
rb_eDLError
=
rb_define_class_under
(
rb_mDL
,
"DLError"
,
rb_eStandardError
);
164
165
/*
166
* Document-class: DL::DLTypeError
167
*
168
* dynamic load incorrect type exception
169
*/
170
rb_eDLTypeError
=
rb_define_class_under
(
rb_mDL
,
"DLTypeError"
,
rb_eDLError
);
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
184
rb_dl_init_callbacks
(
rb_mDL
);
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
374
rb_define_module_function
(
rb_mDL
,
"dlwrap"
,
rb_dl_value2ptr
, 1);
375
rb_define_module_function
(
rb_mDL
,
"dlunwrap"
,
rb_dl_ptr2value
, 1);
376
377
rb_define_module_function
(
rb_mDL
,
"dlopen"
,
rb_dl_dlopen
, -1);
378
rb_define_module_function
(
rb_mDL
,
"malloc"
,
rb_dl_malloc
, 1);
379
rb_define_module_function
(
rb_mDL
,
"realloc"
,
rb_dl_realloc
, 2);
380
rb_define_module_function
(
rb_mDL
,
"free"
,
rb_dl_free
, 1);
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
}
408
Generated on Fri Nov 14 2014 16:03:56 for Ruby by
1.8.3