ext/dl/dl.h


DEFINITIONS

This source file includes following functions.
  1. dlclose
  2. dlopen
  3. dlerror
  4. dlsym
  5. StringValue
  6. StringValuePtr
  7. PUSH_I
  8. ANY2I
  9. DLINT
  10. PUSH_I
  11. ANY2I
  12. DLINT
  13. PUSH_F
  14. ANY2F
  15. DLFLOAT
  16. PUSH_F
  17. ANY2F
  18. DLFLOAT
  19. PUSH_F
  20. ANY2F
  21. DLFLOAT
  22. PUSH_P
  23. ANY2P
  24. DLVOIDP
  25. PUSH_P
  26. ANY2P
  27. DLVOIDP
  28. PUSH_P
  29. ANY2P
  30. DLVOIDP
  31. PUSH_C
  32. ANY2C
  33. DLCHAR
  34. PUSH_C
  35. ANY2C
  36. DLCHAR
  37. PUSH_H
  38. ANY2H
  39. DLSHORT
  40. PUSH_H
  41. ANY2H
  42. DLSHORT
  43. CBPUSH_P
  44. CBPUSH_P
  45. DLSTACK_START
  46. DLSTACK_END
  47. DLSTACK_PUSH_C
  48. DLSTACK_PUSH_H
  49. DLSTACK_PUSH_I
  50. DLSTACK_PUSH_L
  51. DLSTACK_PUSH_P
  52. DLSTACK_PUSH_F
  53. DLSTACK_PUSH_D
  54. DLSTACK_START
  55. DLSTACK_END
  56. DLSTACK_PUSH_C
  57. DLSTACK_PUSH_H
  58. DLSTACK_PUSH_I
  59. DLSTACK_PUSH_L
  60. DLSTACK_PUSH_P
  61. DLSTACK_PUSH_F
  62. DLSTACK_PUSH_D
  63. DLLONG2NUM
  64. DLNUM2LONG
  65. DLLONG2NUM
  66. DLNUM2LONG


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