Module: FFI

Defined in:
lib/ffi/io.rb,
lib/ffi/ffi.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/library.rb,
lib/ffi/pointer.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, 2009 Wayne Meissner Copyright © 2008 Mike Dalessio

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,
}
CURRENT_PROCESS =
USE_THIS_PROCESS_AS_LIBRARY = Object.new
TypeDefs =
typeMap = rb_hash_new()
SizeTypes =
sizeMap = rb_hash_new()
CallbackInfo =
rbffi_FunctionTypeClass
FunctionInfo =
rbffi_FunctionTypeClass
NativeLibrary =

backwards compat library

LibraryClass

Class Method Summary collapse

Class Method Details

.add_typedef(current, add) ⇒ Object

TypeDefs = Hash.new



32
33
34
35
36
37
38
39
40
41
# File 'lib/ffi/types.rb', line 32

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)


42
43
44
45
46
47
48
# File 'lib/ffi/types.rb', line 42

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



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

def self.map_library_name(lib)
  # Mangle the library name to reflect the native library naming conventions
  lib = lib.to_s unless lib.kind_of?(String)
  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



154
155
156
157
158
159
160
161
# File 'lib/ffi/types.rb', line 154

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)


162
163
164
165
166
167
# File 'lib/ffi/types.rb', line 162

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