ffi 1.15.5-x64-mingw-ucrt → 1.16.0-x64-mingw-ucrt
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +54 -0
- data/Gemfile +1 -1
- data/README.md +3 -2
- data/Rakefile +10 -7
- data/ffi.gemspec +2 -2
- data/lib/3.1/ffi_c.so +0 -0
- data/lib/3.2/ffi_c.so +0 -0
- data/lib/ffi/autopointer.rb +7 -22
- data/lib/ffi/compat.rb +43 -0
- data/lib/ffi/data_converter.rb +2 -2
- data/lib/ffi/dynamic_library.rb +89 -0
- data/lib/ffi/enum.rb +18 -11
- data/lib/ffi/ffi.rb +3 -0
- data/lib/ffi/function.rb +71 -0
- data/lib/ffi/library.rb +55 -71
- data/lib/ffi/library_path.rb +109 -0
- data/lib/ffi/managedstruct.rb +1 -1
- data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
- data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
- data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
- data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
- data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
- data/lib/ffi/platform.rb +15 -13
- data/lib/ffi/struct.rb +2 -1
- data/lib/ffi/struct_layout.rb +1 -1
- data/lib/ffi/struct_layout_builder.rb +1 -1
- data/lib/ffi/types.rb +30 -5
- data/lib/ffi/variadic.rb +19 -8
- data/lib/ffi/version.rb +1 -1
- metadata +21 -11
- /data/lib/ffi/platform/{sparc64-linux → sparcv9-linux}/types.conf +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6be6d426dd4c7a4cb5830dcfb8d338d3680166d34e3db1414866d08a2ea1e8e6
|
4
|
+
data.tar.gz: 9ec420e8785e8541fd55f484c104be8f58c55f64749cbfcd4f89305e6922a21e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c3a88ee0d781baa72703011e1e2ef3abb7162da123b2cbdaeba4ce9d8ac2bb85389cf83d04a847c506c7cf110757f3b629fb1a5bf55f4323183630b316993a5
|
7
|
+
data.tar.gz: db0a7d3fcf2c0dd5929f1465944a2c7f3a4e97c884f5f47415faec11f3e66af391c790e20662c726b00146ffdade577d9cc62146e66a1c37ddf99b9aa57c0ccd
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,57 @@
|
|
1
|
+
1.16.0 / 2023-09-23
|
2
|
+
-------------------
|
3
|
+
|
4
|
+
Fixed:
|
5
|
+
* Fix an issue with signed bitmasks when using flags on the most significant bit. #949
|
6
|
+
* Fix FFI::Pointer#initialize using NUM2LL instead of NUM2ULL.
|
7
|
+
* Fix FFI::Type#inspect to properly display the constant name. #1002
|
8
|
+
* Use libffi closure allocations on hppa-Linux. #1017
|
9
|
+
Previously they would segfault.
|
10
|
+
* Fix class name of Symbol#inspect.
|
11
|
+
* Fix MSVC support of libtest. #1028
|
12
|
+
* Fix attach_function of functions ending in ? or ! #971
|
13
|
+
|
14
|
+
Added:
|
15
|
+
* Convert all C-based classes to TypedData and use write barriers. #994, #995, #996, #997, #998, #999, #1000, #1001, #1003, #1004, #1005, #1006, #1007, #1008, #1009, #1010, #1011, #1012
|
16
|
+
This results in less pressure on the garbage collector, since the objects can be promoted to the old generation, which means they only get marked on major GC.
|
17
|
+
* Implement `ObjectSpace.memsize_of()` of all C-based classes.
|
18
|
+
* Make FFI Ractor compatible. #1023
|
19
|
+
Modules extended per `extend FFI::Library` need to be frozen in order to be used by non-main Ractors.
|
20
|
+
This can be done by calling `freeze` below of all C interface definitions.
|
21
|
+
* In a Ractor it's possible to:
|
22
|
+
* load DLLs and call its functions, access its global variables
|
23
|
+
* use builtin typedefs
|
24
|
+
* use and modify ractor local typedefs
|
25
|
+
* define callbacks
|
26
|
+
* receive async callbacks from non-ruby threads
|
27
|
+
* use frozen FFI::Library based modules with all attributes (enums, structs, typedefs, functions, callbacks)
|
28
|
+
* invoke frozen functions and callbacks defined in the main Ractor
|
29
|
+
* use FFI::Struct definitions from the main Ractor
|
30
|
+
* In a Ractor it's impossible to:
|
31
|
+
* create new FFI::Library based modules
|
32
|
+
* create new FFI::Struct definitions
|
33
|
+
* use custom global typedefs
|
34
|
+
* use non-frozen FFI::Library based modules
|
35
|
+
* Allow type retrieval of attached functions+variables. #1023
|
36
|
+
* Make FFI classes `GC.compact` friendly. #1021
|
37
|
+
* Update libffi and disable custom trampoline when using libffi closure allocation. #1020
|
38
|
+
This is because libffi changed the way how closures are allocated to static trampolines.
|
39
|
+
* Add types.conf for loongarch64-linux. #943
|
40
|
+
* Add types.conf for sw_64-linux (Shen Wei 64-bit, based on Alpha). #1018
|
41
|
+
* Add support for aarch64-windows. #1035
|
42
|
+
* Windows: Update LoadLibrary error message to include error code. #1026
|
43
|
+
* Allow private release method for FFI::ManagedStruct and FFI::AutoPointer. #1029
|
44
|
+
* Add support for passing ABI version to FFI.map_library_name. #963
|
45
|
+
This adds the new class FFI::LibraryPath .
|
46
|
+
* Add support for ruby-3.2 to windows binary gem. #1047
|
47
|
+
* Enable debug symbols for `rake compile` builds to ease debugging. #1048
|
48
|
+
|
49
|
+
Removed:
|
50
|
+
* Remove allocator of AbstractMemory. #1013
|
51
|
+
This disables AbstractMemory.new, which has no practical use.
|
52
|
+
* Remove unused FFI::SizeTypes. #1022
|
53
|
+
|
54
|
+
|
1
55
|
1.15.5 / 2022-01-10
|
2
56
|
-------------------
|
3
57
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Ruby-FFI https://github.com/ffi/ffi/wiki
|
1
|
+
# Ruby-FFI https://github.com/ffi/ffi/wiki
|
2
2
|
|
3
3
|
## Description
|
4
4
|
|
@@ -15,6 +15,7 @@ using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi).
|
|
15
15
|
* C structs (also nested), enums and global variables
|
16
16
|
* Callbacks from C to Ruby
|
17
17
|
* Automatic garbage collection of native memory
|
18
|
+
* Usable in Ractor
|
18
19
|
|
19
20
|
## Synopsis
|
20
21
|
|
@@ -62,7 +63,7 @@ On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and
|
|
62
63
|
From rubygems:
|
63
64
|
|
64
65
|
[sudo] gem install ffi
|
65
|
-
|
66
|
+
|
66
67
|
From a Gemfile using git or GitHub
|
67
68
|
|
68
69
|
gem 'ffi', github: 'ffi/ffi', submodules: true
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rbconfig'
|
2
2
|
require 'date'
|
3
3
|
require 'fileutils'
|
4
|
-
require '
|
4
|
+
require 'yaml'
|
5
5
|
require 'rspec/core/rake_task'
|
6
6
|
require 'rubygems/package_task'
|
7
7
|
require 'rake/extensiontask'
|
@@ -30,9 +30,8 @@ CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
|
|
30
30
|
CLEAN.include 'spec/ffi/fixtures/*.o'
|
31
31
|
CLEAN.include 'spec/ffi/embed-test/ext/*.{o,def}'
|
32
32
|
CLEAN.include 'spec/ffi/embed-test/ext/Makefile'
|
33
|
-
CLEAN.include "pkg/ffi
|
34
|
-
CLEAN.include 'lib/
|
35
|
-
CLEAN.include 'lib/2.*'
|
33
|
+
CLEAN.include "pkg/ffi-*-*/"
|
34
|
+
CLEAN.include 'lib/{2,3}.*'
|
36
35
|
|
37
36
|
# clean all shipped files, that are not in git
|
38
37
|
CLEAN.include(
|
@@ -87,6 +86,8 @@ task 'gem:java' => 'java:gem'
|
|
87
86
|
FfiGemHelper.install_tasks
|
88
87
|
# Register windows gems to be pushed to rubygems.org
|
89
88
|
Bundler::GemHelper.instance.cross_platforms = %w[x86-mingw32 x64-mingw-ucrt x64-mingw32]
|
89
|
+
# These platforms are not yet enabled, since there are issues on musl-based distors (alpine-linux):
|
90
|
+
# + %w[x86-linux x86_64-linux arm-linux aarch64-linux x86_64-darwin arm64-darwin]
|
90
91
|
|
91
92
|
if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
|
92
93
|
require 'rake/extensiontask'
|
@@ -99,6 +100,8 @@ if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
|
|
99
100
|
ext.cross_compiling do |spec|
|
100
101
|
spec.files.reject! { |path| File.fnmatch?('ext/*', path) }
|
101
102
|
end
|
103
|
+
# Enable debug info for 'rake compile' but not for 'gem install'
|
104
|
+
ext.config_options << "--enable-debug"
|
102
105
|
|
103
106
|
end
|
104
107
|
else
|
@@ -121,9 +124,9 @@ namespace "gem" do
|
|
121
124
|
desc "Build the native gem for #{plat}"
|
122
125
|
task plat => ['prepare', 'build'] do
|
123
126
|
RakeCompilerDock.sh <<-EOT, platform: plat
|
124
|
-
sudo apt-get update &&
|
125
|
-
|
126
|
-
rake
|
127
|
+
#{ "sudo apt-get update && sudo apt-get install -y libltdl-dev &&" if plat !~ /linux/ }
|
128
|
+
bundle --local &&
|
129
|
+
rake native:#{plat} pkg/#{gem_spec.full_name}-#{plat}.gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=${RUBY_CC_VERSION/:2.4.0/}
|
127
130
|
EOT
|
128
131
|
end
|
129
132
|
end
|
data/ffi.gemspec
CHANGED
@@ -34,9 +34,9 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$]
|
35
35
|
s.license = 'BSD-3-Clause'
|
36
36
|
s.require_paths << 'ext/ffi_c'
|
37
|
-
s.required_ruby_version = '>= 2.
|
37
|
+
s.required_ruby_version = '>= 2.5'
|
38
38
|
s.add_development_dependency 'rake', '~> 13.0'
|
39
|
-
s.add_development_dependency 'rake-compiler', '~> 1.
|
39
|
+
s.add_development_dependency 'rake-compiler', '~> 1.1'
|
40
40
|
s.add_development_dependency 'rake-compiler-dock', '~> 1.0'
|
41
41
|
s.add_development_dependency 'rspec', '~> 2.14.1'
|
42
42
|
end
|
data/lib/3.1/ffi_c.so
CHANGED
Binary file
|
data/lib/3.2/ffi_c.so
ADDED
Binary file
|
data/lib/ffi/autopointer.rb
CHANGED
@@ -76,21 +76,21 @@ module FFI
|
|
76
76
|
# going to be useful if you subclass {AutoPointer}, and override
|
77
77
|
# #release, which by default does nothing.
|
78
78
|
def initialize(ptr, proc=nil, &block)
|
79
|
+
raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) ||
|
80
|
+
ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
|
79
81
|
super(ptr.type_size, ptr)
|
80
|
-
raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) \
|
81
|
-
|| ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
|
82
82
|
|
83
83
|
@releaser = if proc
|
84
84
|
if not proc.respond_to?(:call)
|
85
85
|
raise RuntimeError.new("proc must be callable")
|
86
86
|
end
|
87
|
-
|
87
|
+
Releaser.new(ptr, proc)
|
88
88
|
|
89
89
|
else
|
90
|
-
if not self.class.respond_to?(:release)
|
90
|
+
if not self.class.respond_to?(:release, true)
|
91
91
|
raise RuntimeError.new("no release method defined")
|
92
92
|
end
|
93
|
-
|
93
|
+
Releaser.new(ptr, self.class.method(:release))
|
94
94
|
end
|
95
95
|
|
96
96
|
ObjectSpace.define_finalizer(self, @releaser)
|
@@ -107,6 +107,7 @@ module FFI
|
|
107
107
|
# @return [Boolean] +autorelease+
|
108
108
|
# Set +autorelease+ property. See {Pointer Autorelease section at Pointer}.
|
109
109
|
def autorelease=(autorelease)
|
110
|
+
raise FrozenError.new("can't modify frozen #{self.class}") if frozen?
|
110
111
|
@releaser.autorelease=(autorelease)
|
111
112
|
end
|
112
113
|
|
@@ -149,23 +150,7 @@ module FFI
|
|
149
150
|
def call(*args)
|
150
151
|
release(@ptr) if @autorelease && @ptr
|
151
152
|
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# DefaultReleaser is a {Releaser} used when an {AutoPointer} is defined
|
155
|
-
# without Proc or Method. In this case, the pointer to release must be of
|
156
|
-
# a class derived from AutoPointer with a {release} class method.
|
157
|
-
class DefaultReleaser < Releaser
|
158
|
-
# @param [Pointer] ptr
|
159
|
-
# @return [nil]
|
160
|
-
# Release +ptr+ using the {release} class method of its class.
|
161
|
-
def release(ptr)
|
162
|
-
@proc.release(ptr)
|
163
|
-
end
|
164
|
-
end
|
165
153
|
|
166
|
-
# CallableReleaser is a {Releaser} used when an {AutoPointer} is defined with a
|
167
|
-
# Proc or a Method.
|
168
|
-
class CallableReleaser < Releaser
|
169
154
|
# Release +ptr+ by using Proc or Method defined at +ptr+
|
170
155
|
# {AutoPointer#initialize initialization}.
|
171
156
|
#
|
@@ -182,7 +167,7 @@ module FFI
|
|
182
167
|
# @return [Type::POINTER]
|
183
168
|
# @raise {RuntimeError} if class does not implement a +#release+ method
|
184
169
|
def self.native_type
|
185
|
-
if not self.respond_to?(:release)
|
170
|
+
if not self.respond_to?(:release, true)
|
186
171
|
raise RuntimeError.new("no release method defined for #{self.inspect}")
|
187
172
|
end
|
188
173
|
Type::POINTER
|
data/lib/ffi/compat.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2023-2023 Lars Kanis
|
3
|
+
#
|
4
|
+
# This file is part of ruby-ffi.
|
5
|
+
#
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
15
|
+
# and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of the Ruby FFI project nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
|
32
|
+
module FFI
|
33
|
+
if defined?(Ractor.make_shareable)
|
34
|
+
# This is for FFI internal use only.
|
35
|
+
def self.make_shareable(obj)
|
36
|
+
Ractor.make_shareable(obj)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
def self.make_shareable(obj)
|
40
|
+
obj.freeze
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/ffi/data_converter.rb
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
module FFI
|
32
32
|
# This module is used to extend somes classes and give then a common API.
|
33
33
|
#
|
34
|
-
# Most of methods defined here must be
|
34
|
+
# Most of methods defined here must be overridden.
|
35
35
|
module DataConverter
|
36
36
|
# Get native type.
|
37
37
|
#
|
@@ -41,7 +41,7 @@ module FFI
|
|
41
41
|
# Get native type from +type+.
|
42
42
|
#
|
43
43
|
# @overload native_type
|
44
|
-
# @raise {NotImplementedError} This method must be
|
44
|
+
# @raise {NotImplementedError} This method must be overridden.
|
45
45
|
def native_type(type = nil)
|
46
46
|
if type
|
47
47
|
@native_type = FFI.find_type(type)
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008-2010 Wayne Meissner
|
3
|
+
#
|
4
|
+
# This file is part of ruby-ffi.
|
5
|
+
#
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
15
|
+
# and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of the Ruby FFI project nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
|
30
|
+
|
31
|
+
module FFI
|
32
|
+
class DynamicLibrary
|
33
|
+
SEARCH_PATH = %w[/usr/lib /usr/local/lib /opt/local/lib]
|
34
|
+
if FFI::Platform::ARCH == 'aarch64' && FFI::Platform.mac?
|
35
|
+
SEARCH_PATH << '/opt/homebrew/lib'
|
36
|
+
end
|
37
|
+
|
38
|
+
SEARCH_PATH_MESSAGE = "Searched in <system library path>, #{SEARCH_PATH.join(', ')}".freeze
|
39
|
+
|
40
|
+
def self.load_library(name, flags)
|
41
|
+
if name == FFI::CURRENT_PROCESS
|
42
|
+
FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL)
|
43
|
+
else
|
44
|
+
flags ||= RTLD_LAZY | RTLD_LOCAL
|
45
|
+
|
46
|
+
libnames = (name.is_a?(::Array) ? name : [name])
|
47
|
+
libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact
|
48
|
+
errors = []
|
49
|
+
|
50
|
+
libnames.each do |libname|
|
51
|
+
lib = try_load(libname, flags, errors)
|
52
|
+
return lib if lib
|
53
|
+
|
54
|
+
unless libname.start_with?("/") || FFI::Platform.windows?
|
55
|
+
SEARCH_PATH.each do |prefix|
|
56
|
+
path = "#{prefix}/#{libname}"
|
57
|
+
if File.exist?(path)
|
58
|
+
lib = try_load(path, flags, errors)
|
59
|
+
return lib if lib
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
private_class_method :load_library
|
69
|
+
|
70
|
+
def self.try_load(libname, flags, errors)
|
71
|
+
begin
|
72
|
+
lib = FFI::DynamicLibrary.open(libname, flags)
|
73
|
+
return lib if lib
|
74
|
+
|
75
|
+
# LoadError for C ext & JRuby, RuntimeError for TruffleRuby
|
76
|
+
rescue LoadError, RuntimeError => ex
|
77
|
+
if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
|
78
|
+
if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
|
79
|
+
return try_load($1, flags, errors)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
errors << ex
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
private_class_method :try_load
|
88
|
+
end
|
89
|
+
end
|
data/lib/ffi/enum.rb
CHANGED
@@ -192,6 +192,7 @@ module FFI
|
|
192
192
|
# @param [nil, Symbol] tag name of new Bitmask
|
193
193
|
def initialize(*args)
|
194
194
|
@native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT
|
195
|
+
@signed = [Type::INT8, Type::INT16, Type::INT32, Type::INT64].include?(@native_type)
|
195
196
|
info, @tag = *args
|
196
197
|
@kv_map = Hash.new
|
197
198
|
unless info.nil?
|
@@ -220,7 +221,7 @@ module FFI
|
|
220
221
|
# @param [Symbol] query
|
221
222
|
# @return [Integer]
|
222
223
|
# @overload [](query)
|
223
|
-
# Get
|
224
|
+
# Get bitmask value from symbol array
|
224
225
|
# @param [Array<Symbol>] query
|
225
226
|
# @return [Integer]
|
226
227
|
# @overload [](*query)
|
@@ -240,7 +241,7 @@ module FFI
|
|
240
241
|
when Symbol
|
241
242
|
flat_query.inject(0) do |val, o|
|
242
243
|
v = @kv_map[o]
|
243
|
-
if v then val
|
244
|
+
if v then val | v else val end
|
244
245
|
end
|
245
246
|
when Integer, ->(o) { o.respond_to?(:to_int) }
|
246
247
|
val = flat_query.inject(0) { |mask, o| mask |= o.to_int }
|
@@ -260,35 +261,41 @@ module FFI
|
|
260
261
|
def to_native(query, ctx)
|
261
262
|
return 0 if query.nil?
|
262
263
|
flat_query = [query].flatten
|
263
|
-
flat_query.inject(0) do |val, o|
|
264
|
+
res = flat_query.inject(0) do |val, o|
|
264
265
|
case o
|
265
266
|
when Symbol
|
266
267
|
v = @kv_map[o]
|
267
268
|
raise ArgumentError, "invalid bitmask value, #{o.inspect}" unless v
|
268
|
-
val
|
269
|
+
val | v
|
269
270
|
when Integer
|
270
|
-
val
|
271
|
+
val | o
|
271
272
|
when ->(obj) { obj.respond_to?(:to_int) }
|
272
|
-
val
|
273
|
+
val | o.to_int
|
273
274
|
else
|
274
275
|
raise ArgumentError, "invalid bitmask value, #{o.inspect}"
|
275
276
|
end
|
276
277
|
end
|
278
|
+
# Take two's complement of positive values bigger than the max value
|
279
|
+
# for the type when native type is signed.
|
280
|
+
if @signed && res >= (1 << (@native_type.size * 8 - 1))
|
281
|
+
res = -(-res & ((1 << (@native_type.size * 8)) - 1))
|
282
|
+
end
|
283
|
+
res
|
277
284
|
end
|
278
285
|
|
279
286
|
# @param [Integer] val
|
280
287
|
# @param ctx unused
|
281
288
|
# @return [Array<Symbol, Integer>] list of symbol names corresponding to val, plus an optional remainder if some bits don't match any constant
|
282
289
|
def from_native(val, ctx)
|
283
|
-
|
290
|
+
flags = @kv_map.select { |_, v| v & val != 0 }
|
291
|
+
list = flags.keys
|
292
|
+
# force an unsigned value of the correct size
|
293
|
+
val &= (1 << (@native_type.size * 8)) - 1 if @signed
|
284
294
|
# If there are unmatch flags,
|
285
295
|
# return them in an integer,
|
286
296
|
# else information can be lost.
|
287
297
|
# Similar to Enum behavior.
|
288
|
-
remainder = val ^
|
289
|
-
v = @kv_map[o]
|
290
|
-
if v then tmp |= v else tmp end
|
291
|
-
end
|
298
|
+
remainder = val ^ flags.values.reduce(0, :|)
|
292
299
|
list.push remainder unless remainder == 0
|
293
300
|
return list
|
294
301
|
end
|
data/lib/ffi/ffi.rb
CHANGED
@@ -28,9 +28,11 @@
|
|
28
28
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
29
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
30
|
|
31
|
+
require 'ffi/compat'
|
31
32
|
require 'ffi/platform'
|
32
33
|
require 'ffi/data_converter'
|
33
34
|
require 'ffi/types'
|
35
|
+
require 'ffi/library_path'
|
34
36
|
require 'ffi/library'
|
35
37
|
require 'ffi/errno'
|
36
38
|
require 'ffi/abstract_memory'
|
@@ -45,3 +47,4 @@ require 'ffi/autopointer'
|
|
45
47
|
require 'ffi/variadic'
|
46
48
|
require 'ffi/enum'
|
47
49
|
require 'ffi/version'
|
50
|
+
require 'ffi/function'
|
data/lib/ffi/function.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008-2010 JRuby project
|
3
|
+
#
|
4
|
+
# This file is part of ruby-ffi.
|
5
|
+
#
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
15
|
+
# and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of the Ruby FFI project nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
module FFI
|
32
|
+
class Function
|
33
|
+
# Only MRI allows function type queries
|
34
|
+
if private_method_defined?(:type)
|
35
|
+
# Retrieve the return type of the function
|
36
|
+
#
|
37
|
+
# This method returns FFI type returned by the function.
|
38
|
+
#
|
39
|
+
# @return [FFI::Type]
|
40
|
+
def return_type
|
41
|
+
type.return_type
|
42
|
+
end
|
43
|
+
|
44
|
+
# Retrieve Array of parameter types
|
45
|
+
#
|
46
|
+
# This method returns an Array of FFI types accepted as function parameters.
|
47
|
+
#
|
48
|
+
# @return [Array<FFI::Type>]
|
49
|
+
def param_types
|
50
|
+
type.param_types
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Stash the Function in a module variable so it can be inspected by attached_functions.
|
55
|
+
# On CRuby it also ensures that it does not get garbage collected.
|
56
|
+
module RegisterAttach
|
57
|
+
def attach(mod, name)
|
58
|
+
funcs = mod.instance_variable_get("@ffi_functions")
|
59
|
+
unless funcs
|
60
|
+
funcs = {}
|
61
|
+
mod.instance_variable_set("@ffi_functions", funcs)
|
62
|
+
end
|
63
|
+
funcs[name.to_sym] = self
|
64
|
+
# Jump to the native attach method of CRuby, JRuby or Tuffleruby
|
65
|
+
super
|
66
|
+
end
|
67
|
+
end
|
68
|
+
private_constant :RegisterAttach
|
69
|
+
prepend RegisterAttach
|
70
|
+
end
|
71
|
+
end
|