Project

General

Profile

Bug #6496 ยป ruby-dl_documentation-20120525.patch

vbatts (Vincent Batts), 05/26/2012 03:31 AM

View differences:

ext/dl/dl.c
49 49
#endif
50 50
#define DLTYPE_UINTPTR_T (-DLTYPE_INTPTR_T)
51 51

  
52
/*
53
 * call-seq: DL.dlopen(so_lib)
54
 *
55
 * == Description
56
 * An interface to the dynamic linking loader
57
 *
58
 * This is a shortcut to DL::Handle.new and takes the same arguments.
59
 *
60
 * == Example
61
 *   libc_so = "/lib64/libc.so.6"
62
 *   => "/lib64/libc.so.6"
63
 *   libc = DL.dlopen(libc_so)
64
 *   => #<DL::Handle:0x00000000e05b00>
65
 */
52 66
VALUE
53 67
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
54 68
{
......
56 70
}
57 71

  
58 72
/*
59
 * call-seq: DL.malloc
73
 * call-seq: DL.malloc(size)
60 74
 *
61 75
 * Allocate +size+ bytes of memory and return the integer memory address
62 76
 * for the allocated memory.
......
103 117
    return Qnil;
104 118
}
105 119

  
120
/*
121
 * call-seq: DL.dlunwrap(addr)
122
 *
123
 * returns the hexdecimal representation of a memory pointer address +addr+
124
 *
125
 * == Example
126
 *   lib = DL.dlopen('/lib64/libc-2.15.so')
127
 *   => #<DL::Handle:0x00000001342460>
128
 *   lib['strcpy'].to_s(16)  
129
 *   => "7f59de6dd240"
130
 *   DL.dlunwrap(DL.dlwrap(lib['strcpy'].to_s(16)))
131
 *   => "7f59de6dd240"
132
 */
106 133
VALUE
107 134
rb_dl_ptr2value(VALUE self, VALUE addr)
108 135
{
......
110 137
    return (VALUE)NUM2PTR(addr);
111 138
}
112 139

  
140
/*
141
 * call-seq: DL.dlwrap(val)
142
 *
143
 * returns a memory pointer of a function's hexdecimal address location +val+
144
 *
145
 * == Example
146
 *   lib = DL.dlopen('/lib64/libc-2.15.so')
147
 *   => #<DL::Handle:0x00000001342460>
148
 *   DL.dlwrap(lib['strcpy'].to_s(16))
149
 *   => 25522520
150
 */
113 151
VALUE
114 152
rb_dl_value2ptr(VALUE self, VALUE val)
115 153
{
......
489 527

  
490 528
    /* Document-const: SIZEOF_UINTPTR_T
491 529
     *
492
     * size of a intptr_t
530
     * size of a uintptr_t
493 531
     */
494 532
    rb_define_const(rb_mDL, "SIZEOF_UINTPTR_T",  INT2NUM(sizeof(uintptr_t)));
495 533

  
ext/dl/lib/dl.rb
6 6
end
7 7

  
8 8
module DL
9
  # returns a boolean, of whether Fiddle is defined
9 10
  def self.fiddle?
10 11
    Object.const_defined?(:Fiddle)
11 12
  end
ext/dl/lib/dl/cparser.rb
1 1
module DL
2
  # To be used as a mixin.
2 3
  module CParser
4
    # parses a C struct's members
5
    # 
6
    # == Example
7
    #   parse_struct_signature(['int i', 'char c'])
8
    #   => [[4, 2], ["i", "c"]]
9
    #
3 10
    def parse_struct_signature(signature, tymap=nil)
4 11
      if( signature.is_a?(String) )
5 12
        signature = signature.split(/\s*,\s*/)
......
35 42
      return tys, mems
36 43
    end
37 44

  
45
    # parses a C prototype signature
46
    #
47
    # == Example
48
    #   include DL::CParser
49
    #   => Object
50
    #   parse_signature('double sum(double, double)')
51
    #   => ["sum", 8, [8, 8]]
52
    #
38 53
    def parse_signature(signature, tymap=nil)
39 54
      tymap ||= {}
40 55
      signature = signature.gsub(/\s+/, " ").strip
......
56 71
      end
57 72
    end
58 73

  
74
    # Given a String of C type +ty+, return the corresponding DL constant.
75
    #
76
    # +ty+ can also accept an Array of C type Strings, and will returned in a corresponding Array.
77
    #
78
    # If Hash +tymap+ is provided, +ty+ is expected to be the key,
79
    # and the value will be the C type to be looked up.
80
    #
81
    # == Example
82
    #   parse_ctype('int')
83
    #   => 4
84
    #   parse_ctype('double')
85
    #   => 8
86
    #   parse_ctype('unsigned char')
87
    #   => -2
88
    #
59 89
    def parse_ctype(ty, tymap=nil)
60 90
      tymap ||= {}
61 91
      case ty
ext/dl/lib/dl/import.rb
179 179
      f
180 180
    end
181 181

  
182
    # Given a C struct prototype +signature+, construct a DL::CStruct
182 183
    def struct(signature)
183 184
      tys, mems = parse_struct_signature(signature, @type_alias)
184 185
      DL::CStructBuilder.create(CStruct, tys, mems)
185 186
    end
186 187

  
188
    # Given a C union prototype +signature+, construct a DL::CUnion
187 189
    def union(signature)
188 190
      tys, mems = parse_struct_signature(signature, @type_alias)
189 191
      DL::CStructBuilder.create(CUnion, tys, mems)
ext/dl/lib/dl/struct.rb
2 2
require 'dl/pack.rb'
3 3

  
4 4
module DL
5
  # C struct shell
5 6
  class CStruct
7
    # accesor to DL::CStructEntity
6 8
    def CStruct.entity_class()
7 9
      CStructEntity
8 10
    end
9 11
  end
10 12

  
13
  # C union shell
11 14
  class CUnion
15
    # accesor to DL::CUnionEntity
12 16
    def CUnion.entity_class()
13 17
      CUnionEntity
14 18
    end
15 19
  end
16 20

  
21
  # Used to construct C classes (CUnion, CStruct, etc)
17 22
  module CStructBuilder
23
    # Given a C:
24
    # * class +klass+ (CUnion, CStruct, or other that provide an #entity_class), 
25
    # * +types+ (DL:TYPE_INT, DL::TYPE_SIZE_T, etc., see the C types constants)
26
    # * corresponding +members+
27
    # Construct a new class
28
    #
29
    # == Example
30
    #   require 'dl/struct'
31
    #   => true
32
    #   require 'dl/cparser'
33
    #   => true
34
    #   include DL::CParser
35
    #   => Object
36
    #   types, members = parse_struct_signature(['int i','char c'])
37
    #   => [[4, 2], ["i", "c"]]
38
    #   mystruct = DL::CStructBuilder.create(CUnion, types, members)
39
    #   => #<Class:0x00000001413ab0>
40
    #
18 41
    def create(klass, types, members)
19 42
      new_class = Class.new(klass){
20 43
        define_method(:initialize){|addr|
......
43 66
    module_function :create
44 67
  end
45 68

  
69
  # Subclasses DL::CPtr
46 70
  class CStructEntity < CPtr
47 71
    include PackInfo
48 72
    include ValueUtil
49 73

  
74
    # Uses DL.malloc, to memory allocate for all +types+ provided
50 75
    def CStructEntity.malloc(types, func = nil)
51 76
      addr = DL.malloc(CStructEntity.size(types))
52 77
      CStructEntity.new(addr, types, func)
53 78
    end
54 79

  
80
    # given +types+, returns the offset for the packed sizes of those types
81
    #
82
    #   DL::CStructEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR, DL::TYPE_VOIDP])
83
    #   => 24
84
    #
55 85
    def CStructEntity.size(types)
56 86
      offset = 0
57 87
      max_align = 0
......
76 106
      offset
77 107
    end
78 108

  
109
    # Creates a new pointer to address +addr+ 
110
    # with C +types
111
    #
112
    # Option function +func+ is called when the instance is garbage collected.
113
    # 
114
    # See also DL::CPtr.new
79 115
    def initialize(addr, types, func = nil)
80 116
      set_ctypes(types)
81 117
      super(addr, @size, func)
82 118
    end
83 119

  
120
    # set the names of the +members+ in this C struct
84 121
    def assign_names(members)
85 122
      @members = members
86 123
    end
87 124

  
125
    # given +types+, calculate the necessary offset and size
88 126
    def set_ctypes(types)
89 127
      @ctypes = types
90 128
      @offset = []
......
112 150
      @size = offset
113 151
    end
114 152

  
153
    # fetch member +name+
115 154
    def [](name)
116 155
      idx = @members.index(name)
117 156
      if( idx.nil? )
......
145 184
      end
146 185
    end
147 186

  
187
    # set member +name+, to value +val
148 188
    def []=(name, val)
149 189
      idx = @members.index(name)
150 190
      if( idx.nil? )
......
164 204
      end
165 205
    end
166 206

  
207
    # display as string
167 208
    def to_s()
168 209
      super(@size)
169 210
    end
170 211
  end
171 212

  
213
  # Subclasses DL::CStructEntity
172 214
  class CUnionEntity < CStructEntity
173 215
    include PackInfo
174 216

  
217
    # Uses DL.malloc, to memory allocate for all +types+ provided
175 218
    def CUnionEntity.malloc(types, func=nil)
176 219
      addr = DL.malloc(CUnionEntity.size(types))
177 220
      CUnionEntity.new(addr, types, func)
178 221
    end
179 222

  
223
    # given +types+, return the packed size information for those types
224
    #
225
    #   DL::CUnionEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR, DL::TYPE_VOIDP])
226
    #   => [8, 4, 2, 1]
227
    #
180 228
    def CUnionEntity.size(types)
181 229
      size   = 0
182 230
      types.each_with_index{|t,i|
......
191 239
      }
192 240
    end
193 241

  
242
    # given +types+, calculate the necessary offset and size
194 243
    def set_ctypes(types)
195 244
      @ctypes = types
196 245
      @offset = []