Method: Fiddle.dlopen

Defined in:
lib/fiddle.rb

.dlopen(library) ⇒ Object

call-seq: dlopen(library) => Fiddle::Handle

Creates a new handler that opens library, and returns an instance of Fiddle::Handle.

If nil is given for the library, Fiddle::Handle::DEFAULT is used, which is the equivalent to RTLD_DEFAULT. See man 3 dlopen for more.

lib = Fiddle.dlopen(nil)

The default is dependent on OS, and provide a handle for all libraries already loaded. For example, in most cases you can use this to access libc functions, or ruby functions like rb_str_new.

See Fiddle::Handle.new for more.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/fiddle.rb', line 91

def dlopen library
  begin
    Fiddle::Handle.new(library)
  rescue DLError => error
    case RUBY_PLATFORM
    when /linux/
      case error.message
      when /\A(\/.+?): (?:invalid ELF header|file too short)/
        # This may be a linker script:
        # https://sourceware.org/binutils/docs/ld.html#Scripts
        path = $1
      else
        raise
      end
    else
      raise
    end

    File.open(path) do |input|
      input.each_line do |line|
        case line
        when /\A\s*(?:INPUT|GROUP)\s*\(\s*([^\s,\)]+)/
          # TODO: Should we support multiple files?
          first_input = $1
          if first_input.start_with?("-l")
            first_input = "lib#{first_input[2..-1]}.so"
          end
          return dlopen(first_input)
        end
      end
    end

    # Not found
    raise
  end
end