module FFI::Library

def attach_variable(mname, a1, a2 = nil)

Raises:
  • (FFI::NotFoundError) - if +cname+ cannot be found in libraries

Returns:
  • (DynamicLibrary::Symbol) -

Parameters:
  • type (DataConverter, Struct, Symbol, Type) -- C variable's type
  • mname (#to_s) -- name of ruby method to attach as
  • type (DataConverter, Struct, Symbol, Type) -- C variable's type
  • cname (#to_s) -- name of C variable to attach
  • mname (#to_s) -- name of ruby method to attach as

Overloads:
  • attach_variable(cname, type)
  • attach_variable(mname, cname, type)
def attach_variable(mname, a1, a2 = nil)
  cname, type = a2 ? [ a1, a2 ] : [ mname.to_s, a1 ]
  address = nil
  ffi_libraries.each do |lib|
    begin
      address = lib.find_variable(cname.to_s)
      break unless address.nil?
    rescue LoadError
    end
  end
  raise FFI::NotFoundError.new(cname, ffi_libraries) if address.nil? || address.null?
  if type.is_a?(Class) && type < FFI::Struct
    # If it is a global struct, just attach directly to the pointer
    s = type.new(address)
    self.module_eval <<-code, __FILE__, __LINE__
      @@ffi_gvar_#{mname} = s
      def self.#{mname}
        @@ffi_gvar_#{mname}
      end
    code
  else
    sc = Class.new(FFI::Struct)
    sc.layout :gvar, find_type(type)
    s = sc.new(address)
    #
    # Attach to this module as mname/mname=
    #
    self.module_eval <<-code, __FILE__, __LINE__
      @@ffi_gvar_#{mname} = s
      def self.#{mname}
        @@ffi_gvar_#{mname}[:gvar]
      end
      def self.#{mname}=(value)
        @@ffi_gvar_#{mname}[:gvar] = value
      end
    code
  end
  address
end