Module: FFI

Defined in:
lib/ffi/ffi.rb,
lib/ffi/io.rb,
lib/ffi/ffi.rb,
lib/ffi/enum.rb,
lib/ffi/errno.rb,
lib/ffi/types.rb,
lib/ffi/union.rb,
lib/ffi/struct.rb,
lib/ffi/pointer.rb,
lib/ffi/callback.rb,
lib/ffi/platform.rb,
lib/ffi/variadic.rb,
lib/ffi/autopointer.rb,
lib/ffi/managedstruct.rb,
lib/ffi/memorypointer.rb,
lib/ffi/tools/generator.rb,
lib/ffi/tools/const_generator.rb,
lib/ffi/tools/types_generator.rb,
lib/ffi/tools/struct_generator.rb,
ext/ffi_c/ffi.c

Overview

Copyright © 2008 JRuby project Copyright © 2007, 2008 Evan Phoenix All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of the Evan Phoenix nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Defined Under Namespace

Modules: IO, LastError, Library, NativeType, Platform Classes: AbstractMemory, ArrayType, AutoPointer, Buffer, ConstGenerator, DynamicLibrary, Enum, Enums, Function, FunctionType, Generator, ManagedStruct, MemoryPointer, NativeError, NotFoundError, NullPointerError, PlatformError, Pointer, SignatureError, Struct, StructByValue, StructGenerator, StructLayout, StructLayoutBuilder, Type, TypesGenerator, Union, VariadicInvoker

Constant Summary collapse

TypeSizes =
{
  1 => :char,
  2 => :short,
  4 => :int,
  8 => :long_long,
}
TypeDefs =
typeMap = rb_hash_new()
SizeTypes =
sizeMap = rb_hash_new()
CallbackInfo =
rbffi_FunctionTypeClass
FunctionInfo =
rbffi_FunctionTypeClass
NativeLibrary =

backwards compat library

LibraryClass
TYPE_LONG =
t
TYPE_ULONG =
t

Class Method Summary collapse

Class Method Details

.add_typedef(current, add) ⇒ Object

TypeDefs = Hash.new



3
4
5
6
7
8
9
10
11
12
# File 'lib/ffi/types.rb', line 3

def self.add_typedef(current, add)
  if current.kind_of?(FFI::Type)
    code = current
  else
    code = TypeDefs[current]
    raise TypeError, "Unable to resolve type '#{current}'" unless code
  end

  TypeDefs[add] = code
end

.create_invoker(lib, name, args, ret_type, options = { :convention => :default }) ⇒ Object

Raises:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ffi/ffi.rb', line 71

def self.create_invoker(lib, name, args, ret_type, options = { :convention => :default })
  # Current artificial limitation based on JRuby::FFI limit
  raise SignatureError, 'FFI functions may take max 32 arguments!' if args.size > 32

  # Open the library if needed
  library = if lib.kind_of?(DynamicLibrary)
    lib
  elsif lib.kind_of?(String)
    # Allow FFI.create_invoker to be  called with a library name
    DynamicLibrary.open(FFI.map_library_name(lib), DynamicLibrary::RTLD_LAZY)
  elsif lib.nil?
    FFI::Library::DEFAULT
  else
    raise LoadError, "Invalid library '#{lib}'"
  end
  function = library.find_function(name)
  raise NotFoundError.new(name, library.name) unless function

  args = args.map {|e| find_type(e) }
  invoker = if args.length > 0 && args[args.length - 1] == FFI::NativeType::VARARGS
    FFI::VariadicInvoker.new(function, args, find_type(ret_type), options)
  else
    FFI::Function.new(find_type(ret_type), args, function, options)
  end
  raise NotFoundError.new(name, library.name) unless invoker

  return invoker
end

.errnoObject



2
3
4
# File 'lib/ffi/errno.rb', line 2

def self.errno
  FFI::LastError.error
end

.errno=(error) ⇒ Object



5
6
7
# File 'lib/ffi/errno.rb', line 5

def self.errno=(error)
  FFI::LastError.error = error
end

.find_type(name, type_map = nil) ⇒ Object

Raises:

  • (TypeError)


13
14
15
16
17
18
19
# File 'lib/ffi/types.rb', line 13

def self.find_type(name, type_map = nil)
  type_map = TypeDefs if type_map.nil?
  code = type_map[name]
  code = name if !code && name.kind_of?(FFI::Type)
  raise TypeError, "Unable to resolve type '#{name}'" unless code
  return code
end

.map_library_name(lib) ⇒ Object



59
60
61
62
63
64
65
66
67
68
# File 'lib/ffi/ffi.rb', line 59

def self.map_library_name(lib)
  # Mangle the library name to reflect the native library naming conventions
  lib = Platform::LIBC if Platform::IS_LINUX && lib == 'c'
  if lib && File.basename(lib) == lib
    ext = ".#{Platform::LIBSUFFIX}"
    lib = Platform::LIBPREFIX + lib unless lib =~ /^#{Platform::LIBPREFIX}/
    lib += ext unless lib =~ /#{ext}/
  end
  lib
end

.size_to_type(size) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/ffi/types.rb', line 125

def self.size_to_type(size)
  if sz = TypeSizes[size]
    return sz
  end

  # Be like C, use int as the default type size.
  return :int
end

.type_size(type) ⇒ Object

Raises:

  • (ArgumentError)


133
134
135
136
137
138
# File 'lib/ffi/types.rb', line 133

def self.type_size(type)
  if sz = SizeTypes[find_type(type)]
    return sz
  end
  raise ArgumentError, "Unknown native type"
end