1 | /* -*- C -*-
|
---|
2 | * $Id: dl.h 11708 2007-02-12 23:01:19Z shyouhei $
|
---|
3 | */
|
---|
4 |
|
---|
5 | #ifndef RUBY_DL_H
|
---|
6 | #define RUBY_DL_H
|
---|
7 |
|
---|
8 | #include <ruby.h>
|
---|
9 | #include <dlconfig.h>
|
---|
10 |
|
---|
11 | #if defined(HAVE_DLFCN_H)
|
---|
12 | # include <dlfcn.h>
|
---|
13 | # /* some stranger systems may not define all of these */
|
---|
14 | #ifndef RTLD_LAZY
|
---|
15 | #define RTLD_LAZY 0
|
---|
16 | #endif
|
---|
17 | #ifndef RTLD_GLOBAL
|
---|
18 | #define RTLD_GLOBAL 0
|
---|
19 | #endif
|
---|
20 | #ifndef RTLD_NOW
|
---|
21 | #define RTLD_NOW 0
|
---|
22 | #endif
|
---|
23 | #else
|
---|
24 | # if defined(HAVE_WINDOWS_H)
|
---|
25 | # include <windows.h>
|
---|
26 | # define dlclose(ptr) FreeLibrary((HINSTANCE)ptr)
|
---|
27 | # define dlopen(name,flag) ((void*)LoadLibrary(name))
|
---|
28 | # define dlerror() "unknown error"
|
---|
29 | # define dlsym(handle,name) ((void*)GetProcAddress(handle,name))
|
---|
30 | # define RTLD_LAZY -1
|
---|
31 | # define RTLD_NOW -1
|
---|
32 | # define RTLD_GLOBAL -1
|
---|
33 | # endif
|
---|
34 | #endif
|
---|
35 |
|
---|
36 | #if !defined(StringValue)
|
---|
37 | # define StringValue(v) if(TYPE(v) != T_STRING) v = rb_str_to_str(v)
|
---|
38 | #endif
|
---|
39 | #if !defined(StringValuePtr)
|
---|
40 | # define StringValuePtr(v) RSTRING((TYPE(v) == T_STRING) ? (v) : rb_str_to_str(v))->ptr
|
---|
41 | #endif
|
---|
42 |
|
---|
43 | #ifdef DEBUG
|
---|
44 | #define DEBUG_CODE(b) {printf("DEBUG:%d\n",__LINE__);b;}
|
---|
45 | #define DEBUG_CODE2(b1,b2) {printf("DEBUG:%d\n",__LINE__);b1;}
|
---|
46 | #else
|
---|
47 | #define DEBUG_CODE(b)
|
---|
48 | #define DEBUG_CODE2(b1,b2) b2
|
---|
49 | #endif
|
---|
50 |
|
---|
51 | #define VOID_DLTYPE 0x00
|
---|
52 | #define CHAR_DLTYPE 0x01
|
---|
53 | #define SHORT_DLTYPE 0x02
|
---|
54 | #define INT_DLTYPE 0x03
|
---|
55 | #define LONG_DLTYPE 0x04
|
---|
56 | #define FLOAT_DLTYPE 0x05
|
---|
57 | #define DOUBLE_DLTYPE 0x06
|
---|
58 | #define VOIDP_DLTYPE 0x07
|
---|
59 |
|
---|
60 | #define ARG_TYPE(x,i) (((x) & (0x07 << ((i)*3))) >> ((i)*3))
|
---|
61 | #define PUSH_ARG(x,t) do{x <<= 3; x |= t;}while(0)
|
---|
62 | #define PUSH_0(x) PUSH_ARG(x,VOID_DLTYPE)
|
---|
63 |
|
---|
64 | #if SIZEOF_INT == SIZEOF_LONG
|
---|
65 | # define PUSH_I(x) PUSH_ARG(x,LONG_DLTYPE)
|
---|
66 | # define ANY2I(x) x.l
|
---|
67 | # define DLINT(x) (long)x
|
---|
68 | #else
|
---|
69 | # define PUSH_I(x) PUSH_ARG(x,INT_DLTYPE)
|
---|
70 | # define ANY2I(x) x.i
|
---|
71 | # define DLINT(x) (int)x
|
---|
72 | #endif
|
---|
73 | #define PUSH_L(x) PUSH_ARG(x,LONG_DLTYPE)
|
---|
74 | #define ANY2L(x) x.l
|
---|
75 | #define DLLONG(x) (long)x
|
---|
76 |
|
---|
77 | #if defined(WITH_TYPE_FLOAT)
|
---|
78 | # if SIZEOF_FLOAT == SIZEOF_DOUBLE
|
---|
79 | # define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE)
|
---|
80 | # define ANY2F(x) (x.d)
|
---|
81 | # define DLFLOAT(x) ((double)x)
|
---|
82 | # else
|
---|
83 | # define PUSH_F(x) PUSH_ARG(x,FLOAT_DLTYPE)
|
---|
84 | # define ANY2F(x) (x.f)
|
---|
85 | # define DLFLOAT(x) ((float)x)
|
---|
86 | # endif
|
---|
87 | #else
|
---|
88 | # define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE)
|
---|
89 | # define ANY2F(x) (x.d)
|
---|
90 | # define DLFLOAT(x) ((double)x)
|
---|
91 | #endif
|
---|
92 | #define PUSH_D(x) PUSH_ARG(x,DOUBLE_DLTYPE)
|
---|
93 | #define ANY2D(x) (x.d)
|
---|
94 | #define DLDOUBLE(x) ((double)x)
|
---|
95 |
|
---|
96 | #if SIZEOF_INT == SIZEOF_VOIDP && SIZEOF_INT != SIZEOF_LONG
|
---|
97 | # define PUSH_P(x) PUSH_ARG(x,INT_DLTYPE)
|
---|
98 | # define ANY2P(x) (x.i)
|
---|
99 | # define DLVOIDP(x) ((int)x)
|
---|
100 | #elif SIZEOF_LONG == SIZEOF_VOIDP
|
---|
101 | # define PUSH_P(x) PUSH_ARG(x,LONG_DLTYPE)
|
---|
102 | # define ANY2P(x) (x.l)
|
---|
103 | # define DLVOIDP(x) ((long)x)
|
---|
104 | #else
|
---|
105 | # define PUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE)
|
---|
106 | # define ANY2P(x) (x.p)
|
---|
107 | # define DLVOIDP(x) ((void*)p)
|
---|
108 | #endif
|
---|
109 |
|
---|
110 | #if defined(WITH_TYPE_CHAR)
|
---|
111 | # define PUSH_C(x) PUSH_ARG(x,CHAR_DLTYPE)
|
---|
112 | # define ANY2C(x) (x.c)
|
---|
113 | # define DLCHAR(x) ((char)x)
|
---|
114 | #else
|
---|
115 | # define PUSH_C(x) PUSH_I(x)
|
---|
116 | # define ANY2C(x) ANY2I(x)
|
---|
117 | # define DLCHAR(x) DLINT(x)
|
---|
118 | #endif
|
---|
119 |
|
---|
120 | #if defined(WITH_TYPE_SHORT)
|
---|
121 | # define PUSH_H(x) PUSH_ARG(x,SHORT_DLTYPE)
|
---|
122 | # define ANY2H(x) (x.h)
|
---|
123 | # define DLSHORT(x) ((short)x)
|
---|
124 | #else
|
---|
125 | # define PUSH_H(x) PUSH_I(x)
|
---|
126 | # define ANY2H(x) ANY2I(x)
|
---|
127 | # define DLSHORT(x) DLINT(x)
|
---|
128 | #endif
|
---|
129 |
|
---|
130 | #define PUSH_S(x) PUSH_P(x)
|
---|
131 | #define ANY2S(x) ANY2P(x)
|
---|
132 | #define DLSTR(x) DLVOIDP(x)
|
---|
133 |
|
---|
134 | #define CBPUSH_0(x) PUSH_0(x)
|
---|
135 | #define CBPUSH_C(x) PUSH_C(x)
|
---|
136 | #define CBPUSH_H(x) PUSH_H(x)
|
---|
137 | #define CBPUSH_I(x) PUSH_I(x)
|
---|
138 | #define CBPUSH_L(x) PUSH_L(x)
|
---|
139 | #define CBPUSH_F(x) PUSH_F(x)
|
---|
140 | #define CBPUSH_D(x) PUSH_D(x)
|
---|
141 | #if defined(WITH_CBTYPE_VOIDP)
|
---|
142 | # define CBPUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE)
|
---|
143 | #else
|
---|
144 | # define CBPUSH_P(x) PUSH_P(x)
|
---|
145 | #endif
|
---|
146 |
|
---|
147 |
|
---|
148 | #if defined(USE_INLINE_ASM)
|
---|
149 | # if defined(__i386__) && defined(__GNUC__)
|
---|
150 | # define DLSTACK
|
---|
151 | # define DLSTACK_METHOD "asm"
|
---|
152 | # define DLSTACK_REVERSE
|
---|
153 | # define DLSTACK_PROTO
|
---|
154 | # define DLSTACK_ARGS
|
---|
155 | # define DLSTACK_START(sym)
|
---|
156 | # define DLSTACK_END(sym)
|
---|
157 | # define DLSTACK_PUSH_C(x) asm volatile ("pushl %0" :: "g" (x));
|
---|
158 | # define DLSTACK_PUSH_H(x) asm volatile ("pushl %0" :: "g" (x));
|
---|
159 | # define DLSTACK_PUSH_I(x) asm volatile ("pushl %0" :: "g" (x));
|
---|
160 | # define DLSTACK_PUSH_L(x) asm volatile ("pushl %0" :: "g" (x));
|
---|
161 | # define DLSTACK_PUSH_P(x) asm volatile ("pushl %0" :: "g" (x));
|
---|
162 | # define DLSTACK_PUSH_F(x) asm volatile ("flds %0"::"g"(x));\
|
---|
163 | asm volatile ("subl $4,%esp");\
|
---|
164 | asm volatile ("fstps (%esp)");
|
---|
165 | # define DLSTACK_PUSH_D(x) asm volatile ("fldl %0"::"g"(x));\
|
---|
166 | asm volatile ("subl $8,%esp");\
|
---|
167 | asm volatile ("fstpl (%esp)")
|
---|
168 | # else
|
---|
169 | # error --with-asm is not supported on this machine
|
---|
170 | # endif
|
---|
171 | #elif defined(USE_DLSTACK)
|
---|
172 | # define DLSTACK
|
---|
173 | # define DLSTACK_GUARD
|
---|
174 | # define DLSTACK_METHOD "dl"
|
---|
175 | # define DLSTACK_PROTO long,long,long,long,long,\
|
---|
176 | long,long,long,long,long,\
|
---|
177 | long,long,long,long,long
|
---|
178 | # define DLSTACK_ARGS stack[0],stack[1],stack[2],stack[3],stack[4],\
|
---|
179 | stack[5],stack[6],stack[7],stack[8],stack[9],\
|
---|
180 | stack[10],stack[11],stack[12],stack[13],stack[14]
|
---|
181 | # define DLSTACK_SIZE (sizeof(long)*15)
|
---|
182 | # define DLSTACK_START(sym)
|
---|
183 | # define DLSTACK_END(sym)
|
---|
184 | # define DLSTACK_PUSH_C(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}
|
---|
185 | # define DLSTACK_PUSH_H(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}
|
---|
186 | # define DLSTACK_PUSH_I(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}
|
---|
187 | # define DLSTACK_PUSH_L(x) memcpy(sp,&x,sizeof(long)); sp++;
|
---|
188 | # define DLSTACK_PUSH_P(x) memcpy(sp,&x,sizeof(void*)); sp++;
|
---|
189 | # define DLSTACK_PUSH_F(x) memcpy(sp,&x,sizeof(float)); sp+=sizeof(float)/sizeof(long);
|
---|
190 | # define DLSTACK_PUSH_D(x) memcpy(sp,&x,sizeof(double)); sp+=sizeof(double)/sizeof(long);
|
---|
191 | #else
|
---|
192 | # define DLSTACK_METHOD "none"
|
---|
193 | #endif
|
---|
194 |
|
---|
195 | extern VALUE rb_mDL;
|
---|
196 | extern VALUE rb_mDLMemorySpace;
|
---|
197 | extern VALUE rb_cDLHandle;
|
---|
198 | extern VALUE rb_cDLSymbol;
|
---|
199 | extern VALUE rb_cDLPtrData;
|
---|
200 | extern VALUE rb_cDLStructData;
|
---|
201 |
|
---|
202 | extern VALUE rb_eDLError;
|
---|
203 | extern VALUE rb_eDLTypeError;
|
---|
204 |
|
---|
205 | #if defined(LONG2NUM) && (SIZEOF_LONG == SIZEOF_VOIDP)
|
---|
206 | # define DLLONG2NUM(x) LONG2NUM((long)x)
|
---|
207 | # define DLNUM2LONG(x) (long)(NUM2LONG(x))
|
---|
208 | #else
|
---|
209 | # define DLLONG2NUM(x) INT2NUM((long)x)
|
---|
210 | # define DLNUM2LONG(x) (long)(NUM2INT(x))
|
---|
211 | #endif
|
---|
212 |
|
---|
213 | typedef struct { char c; void *x; } s_voidp;
|
---|
214 | typedef struct { char c; short x; } s_short;
|
---|
215 | typedef struct { char c; int x; } s_int;
|
---|
216 | typedef struct { char c; long x; } s_long;
|
---|
217 | typedef struct { char c; float x; } s_float;
|
---|
218 | typedef struct { char c; double x; } s_double;
|
---|
219 |
|
---|
220 | #define ALIGN_VOIDP (sizeof(s_voidp) - sizeof(void *))
|
---|
221 | #define ALIGN_SHORT (sizeof(s_short) - sizeof(short))
|
---|
222 | #define ALIGN_INT (sizeof(s_int) - sizeof(int))
|
---|
223 | #define ALIGN_LONG (sizeof(s_long) - sizeof(long))
|
---|
224 | #define ALIGN_FLOAT (sizeof(s_float) - sizeof(float))
|
---|
225 | #define ALIGN_DOUBLE (sizeof(s_double) - sizeof(double))
|
---|
226 |
|
---|
227 | /* for compatibility */
|
---|
228 | #define VOIDP_ALIGN ALIGN_VOIDP
|
---|
229 | #define SHORT_ALIGN ALIGN_SHORT
|
---|
230 | #define INT_ALIGN ALIGN_INT
|
---|
231 | #define LONG_ALIGN ALIGN_LONG
|
---|
232 | #define FLOAT_ALIGN ALIGN_FLOAT
|
---|
233 | #define DOUBLE_ALIGN ALIGN_DOUBLE
|
---|
234 |
|
---|
235 | #define DLALIGN(ptr,offset,align) {\
|
---|
236 | while( (((unsigned long)((char *)ptr + offset)) % align) != 0 ) offset++;\
|
---|
237 | }
|
---|
238 |
|
---|
239 | typedef void (*freefunc_t)(void *);
|
---|
240 | #define DLFREEFUNC(func) ((freefunc_t)(func))
|
---|
241 |
|
---|
242 | typedef union {
|
---|
243 | void* p;
|
---|
244 | char c;
|
---|
245 | short h;
|
---|
246 | int i;
|
---|
247 | long l;
|
---|
248 | float f;
|
---|
249 | double d;
|
---|
250 | char *s;
|
---|
251 | } ANY_TYPE;
|
---|
252 |
|
---|
253 | struct dl_handle {
|
---|
254 | void *ptr;
|
---|
255 | int open;
|
---|
256 | int enable_close;
|
---|
257 | };
|
---|
258 |
|
---|
259 | struct sym_data {
|
---|
260 | void *func;
|
---|
261 | char *name;
|
---|
262 | char *type;
|
---|
263 | int len;
|
---|
264 | };
|
---|
265 |
|
---|
266 | enum DLPTR_CTYPE {
|
---|
267 | DLPTR_CTYPE_UNKNOWN,
|
---|
268 | DLPTR_CTYPE_STRUCT,
|
---|
269 | DLPTR_CTYPE_UNION
|
---|
270 | };
|
---|
271 |
|
---|
272 | struct ptr_data {
|
---|
273 | void *ptr; /* a pointer to the data */
|
---|
274 | freefunc_t free; /* free() */
|
---|
275 | char *stype; /* array of type specifiers */
|
---|
276 | int *ssize; /* size[i] = sizeof(type[i]) > 0 */
|
---|
277 | int slen; /* the number of type specifiers */
|
---|
278 | ID *ids;
|
---|
279 | int ids_num;
|
---|
280 | int ctype; /* DLPTR_CTYPE_UNKNOWN, DLPTR_CTYPE_STRUCT, DLPTR_CTYPE_UNION */
|
---|
281 | long size;
|
---|
282 | };
|
---|
283 |
|
---|
284 | #define RDLPTR(obj) ((struct ptr_data *)(DATA_PTR(obj)))
|
---|
285 | #define RDLSYM(obj) ((struct sym_data *)(DATA_PTR(obj)))
|
---|
286 |
|
---|
287 | void dlfree(void*);
|
---|
288 | void *dlmalloc(size_t);
|
---|
289 | void *dlrealloc(void*,size_t);
|
---|
290 | char *dlstrdup(const char *);
|
---|
291 | size_t dlsizeof(const char *);
|
---|
292 |
|
---|
293 | void *rb_ary2cary(char t, VALUE ary, long *size);
|
---|
294 |
|
---|
295 | /*
|
---|
296 | void rb_dlmem_delete(void *ptr);
|
---|
297 | void rb_dlmem_aset(void *ptr, VALUE obj);
|
---|
298 | VALUE rb_dlmem_aref(void *ptr);
|
---|
299 | */
|
---|
300 |
|
---|
301 | void dlptr_free(struct ptr_data *data);
|
---|
302 | void dlptr_init(VALUE val);
|
---|
303 |
|
---|
304 | VALUE rb_dlptr_new(void *ptr, long size, freefunc_t func);
|
---|
305 | VALUE rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func);
|
---|
306 | VALUE rb_dlptr_malloc(long size, freefunc_t func);
|
---|
307 | void *rb_dlptr2cptr(VALUE val);
|
---|
308 |
|
---|
309 | VALUE rb_dlsym_new(void (*func)(), const char *name, const char *type);
|
---|
310 | freefunc_t rb_dlsym2csym(VALUE val);
|
---|
311 |
|
---|
312 |
|
---|
313 | #endif /* RUBY_DL_H */
|
---|