ffi 1.15.5-x64-mingw-ucrt → 1.16.0-x64-mingw-ucrt
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|