ffi 1.16.3 → 1.17.1
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +51 -0
- data/Gemfile +9 -2
- data/README.md +1 -1
- data/Rakefile +18 -6
- data/ext/ffi_c/AbstractMemory.c +39 -38
- data/ext/ffi_c/ArrayType.c +2 -2
- data/ext/ffi_c/Buffer.c +4 -4
- data/ext/ffi_c/Call.c +12 -6
- data/ext/ffi_c/Call.h +3 -2
- data/ext/ffi_c/DynamicLibrary.c +2 -2
- data/ext/ffi_c/Function.c +52 -34
- data/ext/ffi_c/FunctionInfo.c +1 -1
- data/ext/ffi_c/LastError.c +4 -4
- data/ext/ffi_c/MemoryPointer.c +2 -2
- data/ext/ffi_c/Pointer.c +14 -11
- data/ext/ffi_c/Struct.c +11 -4
- data/ext/ffi_c/StructLayout.c +13 -13
- data/ext/ffi_c/Type.c +17 -16
- data/ext/ffi_c/Types.c +7 -1
- data/ext/ffi_c/Types.h +0 -1
- data/ext/ffi_c/Variadic.c +6 -3
- data/ext/ffi_c/libffi/.allow-ai-service +0 -0
- data/ext/ffi_c/libffi/.github/workflows/build.yml +34 -15
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +2 -1
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/README.md +10 -5
- data/ext/ffi_c/libffi/configure +1254 -940
- data/ext/ffi_c/libffi/configure.ac +2 -2
- data/ext/ffi_c/libffi/configure.host +1 -1
- data/ext/ffi_c/libffi/doc/libffi.texi +1 -1
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +6 -6
- data/ext/ffi_c/libffi/include/ffi.h.in +2 -11
- data/ext/ffi_c/libffi/include/ffi_common.h +4 -2
- data/ext/ffi_c/libffi/libffi.map.in +5 -0
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/ltmain.sh +8 -20
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +26 -13
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +198 -46
- data/ext/ffi_c/libffi/src/closures.c +3 -3
- data/ext/ffi_c/libffi/src/debug.c +2 -2
- data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
- data/ext/ffi_c/libffi/src/loongarch64/ffi.c +3 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +12 -4
- data/ext/ffi_c/libffi/src/mips/n32.S +65 -14
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +36 -24
- data/ext/ffi_c/libffi/src/sparc/ffi64.c +7 -1
- data/ext/ffi_c/libffi/src/tramp.c +1 -1
- data/ext/ffi_c/libffi/src/types.c +4 -6
- data/ext/ffi_c/libffi/src/wasm32/ffi.c +13 -0
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +79 -127
- data/ext/ffi_c/libffi/testsuite/Makefile.in +79 -127
- data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +6 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +108 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +114 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +119 -0
- data/ext/ffi_c/libffi.darwin.mk +2 -2
- data/lib/ffi/autopointer.rb +1 -9
- data/lib/ffi/dynamic_library.rb +34 -5
- data/lib/ffi/enum.rb +0 -1
- data/lib/ffi/ffi.rb +59 -0
- data/lib/ffi/function.rb +1 -1
- data/lib/ffi/io.rb +2 -2
- data/lib/ffi/library.rb +23 -23
- data/lib/ffi/platform/aarch64-linux/types.conf +74 -3
- data/lib/ffi/pointer.rb +6 -6
- data/lib/ffi/struct.rb +4 -4
- data/lib/ffi/struct_layout.rb +2 -2
- data/lib/ffi/struct_layout_builder.rb +8 -8
- data/lib/ffi/types.rb +51 -49
- data/lib/ffi/version.rb +1 -1
- data/sig/ffi/abstract_memory.rbs +165 -0
- data/sig/ffi/auto_pointer.rbs +26 -0
- data/sig/ffi/buffer.rbs +18 -0
- data/sig/ffi/data_converter.rbs +10 -0
- data/sig/ffi/dynamic_library.rbs +9 -0
- data/sig/ffi/enum.rbs +38 -0
- data/sig/ffi/function.rbs +39 -0
- data/sig/ffi/library.rbs +42 -0
- data/sig/ffi/native_type.rbs +86 -0
- data/sig/ffi/pointer.rbs +42 -0
- data/sig/ffi/struct.rbs +76 -0
- data/sig/ffi/struct_by_reference.rbs +11 -0
- data/sig/ffi/struct_by_value.rbs +7 -0
- data/sig/ffi/struct_layout.rbs +9 -0
- data/sig/ffi/struct_layout_builder.rbs +5 -0
- data/sig/ffi/type.rbs +39 -0
- data/sig/ffi.rbs +26 -0
- data.tar.gz.sig +0 -0
- metadata +37 -18
- metadata.gz.sig +0 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
/* Area: ffi_call
|
2
|
+
Purpose: Check structures with array and callback.
|
3
|
+
Limitations: none.
|
4
|
+
PR: none.
|
5
|
+
Originator: David Tenty <daltenty@ibm.com> */
|
6
|
+
|
7
|
+
/* { dg-do run } */
|
8
|
+
#include "ffitest.h"
|
9
|
+
|
10
|
+
int i=5;
|
11
|
+
|
12
|
+
void callback(void) { i++; }
|
13
|
+
|
14
|
+
|
15
|
+
typedef struct
|
16
|
+
{
|
17
|
+
unsigned char c1;
|
18
|
+
struct { double d; unsigned char c; } s[2];
|
19
|
+
unsigned char c2;
|
20
|
+
} test_structure_12;
|
21
|
+
|
22
|
+
static test_structure_12 ABI_ATTR struct12 (test_structure_12 ts, void (*func)(void))
|
23
|
+
{
|
24
|
+
ts.c1 += 1;
|
25
|
+
ts.s[0].d += 1;
|
26
|
+
ts.s[0].c += 1;
|
27
|
+
ts.s[1].d += 1;
|
28
|
+
ts.s[1].c += 1;
|
29
|
+
ts.c2 += 1;
|
30
|
+
|
31
|
+
func();
|
32
|
+
return ts;
|
33
|
+
}
|
34
|
+
|
35
|
+
int main (void)
|
36
|
+
{
|
37
|
+
ffi_cif cif;
|
38
|
+
ffi_type *args[MAX_ARGS];
|
39
|
+
void *values[MAX_ARGS];
|
40
|
+
ffi_type ts12_type,ts12b_type, ts12a_type;
|
41
|
+
ffi_type *ts12_type_elements[4];
|
42
|
+
ffi_type *ts12b_type_elements[3];
|
43
|
+
ffi_type *ts12a_type_elements[3];
|
44
|
+
|
45
|
+
test_structure_12 ts12_arg;
|
46
|
+
void (*ptr)(void)=&callback;
|
47
|
+
|
48
|
+
test_structure_12 *ts12_result =
|
49
|
+
(test_structure_12 *) malloc (sizeof(test_structure_12));
|
50
|
+
|
51
|
+
ts12a_type.size = 0;
|
52
|
+
ts12a_type.alignment = 0;
|
53
|
+
ts12a_type.type = FFI_TYPE_STRUCT;
|
54
|
+
ts12a_type.elements = ts12a_type_elements;
|
55
|
+
ts12a_type_elements[0] = &ffi_type_double;
|
56
|
+
ts12a_type_elements[1] = &ffi_type_uchar;
|
57
|
+
ts12a_type_elements[2] = NULL;
|
58
|
+
|
59
|
+
ts12b_type.size = 0;
|
60
|
+
ts12b_type.alignment = 0;
|
61
|
+
ts12b_type.type = FFI_TYPE_STRUCT;
|
62
|
+
ts12b_type.elements = ts12b_type_elements;
|
63
|
+
ts12b_type_elements[0] = &ts12a_type;
|
64
|
+
ts12b_type_elements[1] = &ts12a_type;
|
65
|
+
ts12b_type_elements[2] = NULL;
|
66
|
+
|
67
|
+
ts12_type.size = 0;
|
68
|
+
ts12_type.alignment = 0;
|
69
|
+
ts12_type.type = FFI_TYPE_STRUCT;
|
70
|
+
ts12_type.elements = ts12_type_elements;
|
71
|
+
ts12_type_elements[0] = &ffi_type_uchar;
|
72
|
+
ts12_type_elements[1] = &ts12b_type;
|
73
|
+
ts12_type_elements[2] = &ffi_type_uchar;
|
74
|
+
ts12_type_elements[3] = NULL;
|
75
|
+
|
76
|
+
|
77
|
+
args[0] = &ts12_type;
|
78
|
+
args[1] = &ffi_type_pointer;
|
79
|
+
values[0] = &ts12_arg;
|
80
|
+
values[1] = &ptr;
|
81
|
+
|
82
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts12_type, args) == FFI_OK);
|
83
|
+
|
84
|
+
ts12_arg.c1 = 5;
|
85
|
+
ts12_arg.s[0].d = 5.55;
|
86
|
+
ts12_arg.s[0].c = 6;
|
87
|
+
ts12_arg.s[1].d = 7.77;
|
88
|
+
ts12_arg.s[1].c = 8;
|
89
|
+
ts12_arg.c2 = 9;
|
90
|
+
|
91
|
+
printf ("%u\n", ts12_arg.c1);
|
92
|
+
printf ("%g\n", ts12_arg.s[0].d);
|
93
|
+
printf ("%u\n", ts12_arg.s[0].c);
|
94
|
+
printf ("%g\n", ts12_arg.s[1].d);
|
95
|
+
printf ("%u\n", ts12_arg.s[1].c);
|
96
|
+
printf ("%u\n", ts12_arg.c2);
|
97
|
+
printf ("%d\n", i);
|
98
|
+
|
99
|
+
ffi_call(&cif, FFI_FN(struct12), ts12_result, values);
|
100
|
+
|
101
|
+
printf ("%u\n", ts12_result->c1);
|
102
|
+
printf ("%g\n", ts12_result->s[0].d);
|
103
|
+
printf ("%u\n", ts12_result->s[0].c);
|
104
|
+
printf ("%g\n", ts12_result->s[1].d);
|
105
|
+
printf ("%u\n", ts12_result->s[1].c);
|
106
|
+
printf ("%u\n", ts12_result->c2);
|
107
|
+
printf ("%d\n", i);
|
108
|
+
CHECK(ts12_result->c1 == 5 + 1);
|
109
|
+
CHECK(ts12_result->s[0].d == 5.55 + 1);
|
110
|
+
CHECK(ts12_result->s[0].c == 6 + 1);
|
111
|
+
CHECK(ts12_result->s[1].d == 7.77 + 1);
|
112
|
+
CHECK(ts12_result->s[1].c == 8 + 1);
|
113
|
+
CHECK(ts12_result->c2 == 9 + 1);
|
114
|
+
CHECK(i == 5 + 1);
|
115
|
+
CHECK(ts12_type.size == sizeof(test_structure_12));
|
116
|
+
|
117
|
+
free (ts12_result);
|
118
|
+
exit(0);
|
119
|
+
}
|
data/ext/ffi_c/libffi.darwin.mk
CHANGED
@@ -37,7 +37,7 @@ $(LIBFFI):
|
|
37
37
|
echo "Configuring libffi"; \
|
38
38
|
cd "$(LIBFFI_BUILD_DIR)" && \
|
39
39
|
/usr/bin/env CC="$(CC)" LD="$(LD)" CFLAGS="$(LIBFFI_CFLAGS)" GREP_OPTIONS="" \
|
40
|
-
/bin/sh $(LIBFFI_CONFIGURE) $(LIBFFI_HOST) > /dev/null; \
|
40
|
+
/bin/sh $(LIBFFI_CONFIGURE) $(LIBFFI_HOST) --disable-shared --enable-static > /dev/null; \
|
41
41
|
fi
|
42
42
|
cd "$(LIBFFI_BUILD_DIR)" && $(MAKE)
|
43
43
|
|
@@ -56,7 +56,7 @@ build_ffi = \
|
|
56
56
|
echo "Configuring libffi for $(1)"; \
|
57
57
|
cd "$(BUILD_DIR)"/libffi-$(1) && \
|
58
58
|
env CC="$(CCACHE) $(CC)" CFLAGS="-arch $(1) $(LIBFFI_CFLAGS)" LDFLAGS="-arch $(1)" \
|
59
|
-
$(LIBFFI_CONFIGURE) --host=$(1)-apple-darwin > /dev/null; \
|
59
|
+
$(LIBFFI_CONFIGURE) --host=$(1)-apple-darwin --disable-shared --enable-static > /dev/null; \
|
60
60
|
fi); \
|
61
61
|
$(MAKE) -C "$(BUILD_DIR)"/libffi-$(1)
|
62
62
|
|
data/lib/ffi/autopointer.rb
CHANGED
@@ -45,14 +45,6 @@ module FFI
|
|
45
45
|
# @note WARNING: passing a proc _may_ cause your pointer to never be
|
46
46
|
# GC'd, unless you're careful to avoid trapping a reference to the
|
47
47
|
# pointer in the proc. See the test specs for examples.
|
48
|
-
# @overload initialize(pointer) { |p| ... }
|
49
|
-
# @param pointer [Pointer]
|
50
|
-
# @yieldparam [Pointer] p +pointer+ passed to the block
|
51
|
-
# @return [self]
|
52
|
-
# The passed block will be invoked at GC time.
|
53
|
-
# @note
|
54
|
-
# WARNING: passing a block will cause your pointer to never be GC'd.
|
55
|
-
# This is bad.
|
56
48
|
# @overload initialize(pointer)
|
57
49
|
# @param pointer [Pointer]
|
58
50
|
# @return [self]
|
@@ -75,7 +67,7 @@ module FFI
|
|
75
67
|
# The last calling idiom (only one parameter) is generally only
|
76
68
|
# going to be useful if you subclass {AutoPointer}, and override
|
77
69
|
# #release, which by default does nothing.
|
78
|
-
def initialize(ptr, proc=nil
|
70
|
+
def initialize(ptr, proc=nil)
|
79
71
|
raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) ||
|
80
72
|
ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
|
81
73
|
super(ptr.type_size, ptr)
|
data/lib/ffi/dynamic_library.rb
CHANGED
@@ -30,12 +30,41 @@
|
|
30
30
|
|
31
31
|
module FFI
|
32
32
|
class DynamicLibrary
|
33
|
-
SEARCH_PATH =
|
34
|
-
|
35
|
-
|
33
|
+
SEARCH_PATH = []
|
34
|
+
|
35
|
+
# The following search paths are tried, if the library could not be loaded in the first attempt.
|
36
|
+
# They are only executed on Macos in the following order:
|
37
|
+
if FFI::Platform.mac?
|
38
|
+
|
39
|
+
# 1. Try library paths possibly defined in LD_LIBRARY_PATH DYLD_LIBRARY_PATH first.
|
40
|
+
# This is because dlopen doesn't respect LD_LIBRARY_PATH and DYLD_LIBRARY_PATH is deleted by SIP-protected binaries.
|
41
|
+
# See here for details: https://github.com/ffi/ffi/issues/923#issuecomment-1872565313
|
42
|
+
%w[LD_LIBRARY_PATH DYLD_LIBRARY_PATH].each do |custom_path|
|
43
|
+
SEARCH_PATH.concat ENV.fetch(custom_path,"").split(File::PATH_SEPARATOR)
|
44
|
+
end
|
45
|
+
|
46
|
+
# 2. Then on macos/arm64 try /opt/homebrew/lib, since this is a typical standard directory.
|
47
|
+
# FFI is often used together with homebrew, so that we hardcode the path for arm64 here.
|
48
|
+
if FFI::Platform::ARCH == 'aarch64'
|
49
|
+
SEARCH_PATH << '/opt/homebrew/lib'
|
50
|
+
end
|
51
|
+
|
52
|
+
# 3. Then try typical system directories starting with the /local/ directory first.
|
53
|
+
#
|
54
|
+
# /usr/local/lib is used by homebrow on x86_64.
|
55
|
+
# /opt/local/lib is used by MacPorts and Fink.
|
56
|
+
# /usr/lib is there, because it was always there.
|
57
|
+
SEARCH_PATH.concat %w[/opt/local/lib /usr/local/lib /usr/lib]
|
36
58
|
end
|
37
59
|
|
38
|
-
|
60
|
+
# On Linux the library lookup paths are usually defined through /etc/ld.so.conf, which can be changed at will with root permissions.
|
61
|
+
# Also LD_LIBRARY_PATH is respected by the dynamic loader, so that there's usually no need and no advantage to do a fallback handling.
|
62
|
+
#
|
63
|
+
# Windows has it's own library lookup logic, very different to what we do here.
|
64
|
+
# See: https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#user-content-dll-loading
|
65
|
+
|
66
|
+
FFI.make_shareable(SEARCH_PATH)
|
67
|
+
SEARCH_PATH_MESSAGE = "Searched in <system library path>#{ SEARCH_PATH.map{|a| ', ' + a}.join }".freeze
|
39
68
|
|
40
69
|
def self.load_library(name, flags)
|
41
70
|
if name == FFI::CURRENT_PROCESS
|
@@ -51,7 +80,7 @@ module FFI
|
|
51
80
|
lib = try_load(libname, flags, errors)
|
52
81
|
return lib if lib
|
53
82
|
|
54
|
-
unless libname.start_with?("/")
|
83
|
+
unless libname.start_with?("/")
|
55
84
|
SEARCH_PATH.each do |prefix|
|
56
85
|
path = "#{prefix}/#{libname}"
|
57
86
|
if File.exist?(path)
|
data/lib/ffi/enum.rb
CHANGED
data/lib/ffi/ffi.rb
CHANGED
@@ -48,3 +48,62 @@ require 'ffi/variadic'
|
|
48
48
|
require 'ffi/enum'
|
49
49
|
require 'ffi/version'
|
50
50
|
require 'ffi/function'
|
51
|
+
|
52
|
+
module FFI
|
53
|
+
module ModernForkTracking
|
54
|
+
def _fork
|
55
|
+
pid = super
|
56
|
+
if pid == 0
|
57
|
+
FFI._async_cb_dispatcher_atfork_child
|
58
|
+
end
|
59
|
+
pid
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module LegacyForkTracking
|
64
|
+
module KernelExt
|
65
|
+
def fork
|
66
|
+
if block_given?
|
67
|
+
super do
|
68
|
+
FFI._async_cb_dispatcher_atfork_child
|
69
|
+
yield
|
70
|
+
end
|
71
|
+
else
|
72
|
+
pid = super
|
73
|
+
FFI._async_cb_dispatcher_atfork_child if pid.nil?
|
74
|
+
pid
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module KernelExtPrivate
|
80
|
+
include KernelExt
|
81
|
+
private :fork
|
82
|
+
end
|
83
|
+
|
84
|
+
module IOExt
|
85
|
+
def popen(*args)
|
86
|
+
return super unless args[0] == '-'
|
87
|
+
|
88
|
+
super(*args) do |pipe|
|
89
|
+
FFI._async_cb_dispatcher_atfork_child if pipe.nil?
|
90
|
+
yield pipe
|
91
|
+
end
|
92
|
+
end
|
93
|
+
ruby2_keywords :popen if respond_to?(:ruby2_keywords)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if Process.respond_to?(:_fork)
|
98
|
+
# The nice Ruby 3.1+ way of doing things
|
99
|
+
::Process.singleton_class.prepend(ModernForkTracking)
|
100
|
+
elsif Process.respond_to?(:fork)
|
101
|
+
# Barf. Old CRuby.
|
102
|
+
# Most of the inspiration for how to do this was stolen from ActiveSupport.
|
103
|
+
::Object.prepend(LegacyForkTracking::KernelExtPrivate)
|
104
|
+
::Object.singleton_class.prepend(LegacyForkTracking::KernelExt)
|
105
|
+
::Kernel.prepend(LegacyForkTracking::KernelExtPrivate)
|
106
|
+
::Kernel.singleton_class.prepend(LegacyForkTracking::KernelExt)
|
107
|
+
::IO.singleton_class.prepend(LegacyForkTracking::IOExt)
|
108
|
+
end
|
109
|
+
end
|
data/lib/ffi/function.rb
CHANGED
@@ -55,7 +55,7 @@ module FFI
|
|
55
55
|
# On CRuby it also ensures that it does not get garbage collected.
|
56
56
|
module RegisterAttach
|
57
57
|
def attach(mod, name)
|
58
|
-
funcs = mod.instance_variable_get("@ffi_functions")
|
58
|
+
funcs = mod.instance_variable_defined?("@ffi_functions") && mod.instance_variable_get("@ffi_functions")
|
59
59
|
unless funcs
|
60
60
|
funcs = {}
|
61
61
|
mod.instance_variable_set("@ffi_functions", funcs)
|
data/lib/ffi/io.rb
CHANGED
@@ -42,9 +42,9 @@ module FFI
|
|
42
42
|
|
43
43
|
# @param [#read] io io to read from
|
44
44
|
# @param [AbstractMemory] buf destination for data read from +io+
|
45
|
-
# @param [nil,
|
45
|
+
# @param [nil, Integer] len maximul number of bytes to read from +io+. If +nil+,
|
46
46
|
# read until end of file.
|
47
|
-
# @return [
|
47
|
+
# @return [Integer] length really read, in bytes
|
48
48
|
#
|
49
49
|
# A version of IO#read that reads data from an IO and put then into a native buffer.
|
50
50
|
#
|
data/lib/ffi/library.rb
CHANGED
@@ -135,7 +135,7 @@ module FFI
|
|
135
135
|
# ffi_lib_flags(:lazy, :local) # => 5
|
136
136
|
#
|
137
137
|
# @param [Symbol, …] flags (see {FlagsMap})
|
138
|
-
# @return [
|
138
|
+
# @return [Integer] the new value
|
139
139
|
def ffi_lib_flags(*flags)
|
140
140
|
@ffi_lib_flags = flags.inject(0) { |result, f| result | FlagsMap[f] }
|
141
141
|
end
|
@@ -395,6 +395,26 @@ module FFI
|
|
395
395
|
end
|
396
396
|
end
|
397
397
|
|
398
|
+
# @param [DataConverter, Type, Struct, Symbol] t type to find
|
399
|
+
# @return [Type]
|
400
|
+
# Find a type definition.
|
401
|
+
def find_type(t)
|
402
|
+
if t.kind_of?(Type)
|
403
|
+
t
|
404
|
+
|
405
|
+
elsif defined?(@ffi_typedefs) && @ffi_typedefs.has_key?(t)
|
406
|
+
@ffi_typedefs[t]
|
407
|
+
|
408
|
+
elsif t.is_a?(Class) && t < Struct
|
409
|
+
Type::POINTER
|
410
|
+
|
411
|
+
elsif t.is_a?(DataConverter)
|
412
|
+
# Add a typedef so next time the converter is used, it hits the cache
|
413
|
+
typedef Type::Mapped.new(t), t
|
414
|
+
|
415
|
+
end || FFI.find_type(t)
|
416
|
+
end
|
417
|
+
|
398
418
|
private
|
399
419
|
# Generic enum builder
|
400
420
|
# @param [Class] klass can be one of FFI::Enum or FFI::Bitmask
|
@@ -515,26 +535,6 @@ module FFI
|
|
515
535
|
@ffi_enums.__map_symbol(symbol)
|
516
536
|
end
|
517
537
|
|
518
|
-
# @param [DataConverter, Type, Struct, Symbol] t type to find
|
519
|
-
# @return [Type]
|
520
|
-
# Find a type definition.
|
521
|
-
def find_type(t)
|
522
|
-
if t.kind_of?(Type)
|
523
|
-
t
|
524
|
-
|
525
|
-
elsif defined?(@ffi_typedefs) && @ffi_typedefs.has_key?(t)
|
526
|
-
@ffi_typedefs[t]
|
527
|
-
|
528
|
-
elsif t.is_a?(Class) && t < Struct
|
529
|
-
Type::POINTER
|
530
|
-
|
531
|
-
elsif t.is_a?(DataConverter)
|
532
|
-
# Add a typedef so next time the converter is used, it hits the cache
|
533
|
-
typedef Type::Mapped.new(t), t
|
534
|
-
|
535
|
-
end || FFI.find_type(t)
|
536
|
-
end
|
537
|
-
|
538
538
|
# Retrieve all attached functions and their function signature
|
539
539
|
#
|
540
540
|
# This method returns a Hash of method names of attached functions connected by #attach_function and the corresponding function type.
|
@@ -552,10 +552,10 @@ module FFI
|
|
552
552
|
# @return [Hash< Symbol => ffi_type >]
|
553
553
|
def attached_variables
|
554
554
|
(
|
555
|
-
(@ffi_gsvars
|
555
|
+
(defined?(@ffi_gsvars) ? @ffi_gsvars : {}).map do |name, gvar|
|
556
556
|
[name, gvar.class]
|
557
557
|
end +
|
558
|
-
(@ffi_gvars
|
558
|
+
(defined?(@ffi_gvars) ? @ffi_gvars : {}).map do |name, gvar|
|
559
559
|
[name, gvar.layout[:gvar].type]
|
560
560
|
end
|
561
561
|
).to_h
|
@@ -1,5 +1,4 @@
|
|
1
1
|
rbx.platform.typedef.*__caddr_t = char
|
2
|
-
rbx.platform.typedef.*__qaddr_t = long
|
3
2
|
rbx.platform.typedef.__blkcnt64_t = long
|
4
3
|
rbx.platform.typedef.__blkcnt_t = long
|
5
4
|
rbx.platform.typedef.__blksize_t = int
|
@@ -21,7 +20,43 @@ rbx.platform.typedef.__int16_t = short
|
|
21
20
|
rbx.platform.typedef.__int32_t = int
|
22
21
|
rbx.platform.typedef.__int64_t = long
|
23
22
|
rbx.platform.typedef.__int8_t = char
|
23
|
+
rbx.platform.typedef.__int_least16_t = short
|
24
|
+
rbx.platform.typedef.__int_least32_t = int
|
25
|
+
rbx.platform.typedef.__int_least64_t = long
|
26
|
+
rbx.platform.typedef.__int_least8_t = char
|
27
|
+
rbx.platform.typedef.__intmax_t = long
|
24
28
|
rbx.platform.typedef.__intptr_t = long
|
29
|
+
rbx.platform.typedef.__kernel_caddr_t = string
|
30
|
+
rbx.platform.typedef.__kernel_clock_t = long
|
31
|
+
rbx.platform.typedef.__kernel_clockid_t = int
|
32
|
+
rbx.platform.typedef.__kernel_daddr_t = int
|
33
|
+
rbx.platform.typedef.__kernel_gid16_t = ushort
|
34
|
+
rbx.platform.typedef.__kernel_gid32_t = uint
|
35
|
+
rbx.platform.typedef.__kernel_gid_t = uint
|
36
|
+
rbx.platform.typedef.__kernel_ino_t = ulong
|
37
|
+
rbx.platform.typedef.__kernel_ipc_pid_t = int
|
38
|
+
rbx.platform.typedef.__kernel_key_t = int
|
39
|
+
rbx.platform.typedef.__kernel_loff_t = long_long
|
40
|
+
rbx.platform.typedef.__kernel_long_t = long
|
41
|
+
rbx.platform.typedef.__kernel_mode_t = uint
|
42
|
+
rbx.platform.typedef.__kernel_mqd_t = int
|
43
|
+
rbx.platform.typedef.__kernel_off_t = long
|
44
|
+
rbx.platform.typedef.__kernel_old_dev_t = uint
|
45
|
+
rbx.platform.typedef.__kernel_old_gid_t = ushort
|
46
|
+
rbx.platform.typedef.__kernel_old_time_t = long
|
47
|
+
rbx.platform.typedef.__kernel_old_uid_t = ushort
|
48
|
+
rbx.platform.typedef.__kernel_pid_t = int
|
49
|
+
rbx.platform.typedef.__kernel_ptrdiff_t = long
|
50
|
+
rbx.platform.typedef.__kernel_size_t = ulong
|
51
|
+
rbx.platform.typedef.__kernel_ssize_t = long
|
52
|
+
rbx.platform.typedef.__kernel_suseconds_t = long
|
53
|
+
rbx.platform.typedef.__kernel_time64_t = long_long
|
54
|
+
rbx.platform.typedef.__kernel_time_t = long
|
55
|
+
rbx.platform.typedef.__kernel_timer_t = int
|
56
|
+
rbx.platform.typedef.__kernel_uid16_t = ushort
|
57
|
+
rbx.platform.typedef.__kernel_uid32_t = uint
|
58
|
+
rbx.platform.typedef.__kernel_uid_t = uint
|
59
|
+
rbx.platform.typedef.__kernel_ulong_t = ulong
|
25
60
|
rbx.platform.typedef.__key_t = int
|
26
61
|
rbx.platform.typedef.__loff_t = long
|
27
62
|
rbx.platform.typedef.__mode_t = uint
|
@@ -38,11 +73,14 @@ rbx.platform.typedef.__rusage_who_t = int
|
|
38
73
|
rbx.platform.typedef.__sig_atomic_t = int
|
39
74
|
rbx.platform.typedef.__socklen_t = uint
|
40
75
|
rbx.platform.typedef.__ssize_t = long
|
76
|
+
rbx.platform.typedef.__suseconds64_t = long
|
41
77
|
rbx.platform.typedef.__suseconds_t = long
|
42
78
|
rbx.platform.typedef.__syscall_slong_t = long
|
43
79
|
rbx.platform.typedef.__syscall_ulong_t = ulong
|
80
|
+
rbx.platform.typedef.__thrd_t = ulong
|
44
81
|
rbx.platform.typedef.__time_t = long
|
45
82
|
rbx.platform.typedef.__timer_t = pointer
|
83
|
+
rbx.platform.typedef.__tss_t = uint
|
46
84
|
rbx.platform.typedef.__u_char = uchar
|
47
85
|
rbx.platform.typedef.__u_int = uint
|
48
86
|
rbx.platform.typedef.__u_long = ulong
|
@@ -53,6 +91,11 @@ rbx.platform.typedef.__uint16_t = ushort
|
|
53
91
|
rbx.platform.typedef.__uint32_t = uint
|
54
92
|
rbx.platform.typedef.__uint64_t = ulong
|
55
93
|
rbx.platform.typedef.__uint8_t = uchar
|
94
|
+
rbx.platform.typedef.__uint_least16_t = ushort
|
95
|
+
rbx.platform.typedef.__uint_least32_t = uint
|
96
|
+
rbx.platform.typedef.__uint_least64_t = ulong
|
97
|
+
rbx.platform.typedef.__uint_least8_t = uchar
|
98
|
+
rbx.platform.typedef.__uintmax_t = ulong
|
56
99
|
rbx.platform.typedef.__useconds_t = uint
|
57
100
|
rbx.platform.typedef.blkcnt_t = long
|
58
101
|
rbx.platform.typedef.blksize_t = int
|
@@ -65,11 +108,23 @@ rbx.platform.typedef.fsblkcnt_t = ulong
|
|
65
108
|
rbx.platform.typedef.fsfilcnt_t = ulong
|
66
109
|
rbx.platform.typedef.gid_t = uint
|
67
110
|
rbx.platform.typedef.id_t = uint
|
111
|
+
rbx.platform.typedef.in_addr_t = uint
|
112
|
+
rbx.platform.typedef.in_port_t = ushort
|
68
113
|
rbx.platform.typedef.ino_t = ulong
|
69
114
|
rbx.platform.typedef.int16_t = short
|
70
115
|
rbx.platform.typedef.int32_t = int
|
71
|
-
rbx.platform.typedef.int64_t =
|
116
|
+
rbx.platform.typedef.int64_t = long
|
72
117
|
rbx.platform.typedef.int8_t = char
|
118
|
+
rbx.platform.typedef.int_fast16_t = long
|
119
|
+
rbx.platform.typedef.int_fast32_t = long
|
120
|
+
rbx.platform.typedef.int_fast64_t = long
|
121
|
+
rbx.platform.typedef.int_fast8_t = char
|
122
|
+
rbx.platform.typedef.int_least16_t = short
|
123
|
+
rbx.platform.typedef.int_least32_t = int
|
124
|
+
rbx.platform.typedef.int_least64_t = long
|
125
|
+
rbx.platform.typedef.int_least8_t = char
|
126
|
+
rbx.platform.typedef.intmax_t = long
|
127
|
+
rbx.platform.typedef.intptr_t = long
|
73
128
|
rbx.platform.typedef.key_t = int
|
74
129
|
rbx.platform.typedef.loff_t = long
|
75
130
|
rbx.platform.typedef.mode_t = uint
|
@@ -79,6 +134,7 @@ rbx.platform.typedef.pid_t = int
|
|
79
134
|
rbx.platform.typedef.pthread_key_t = uint
|
80
135
|
rbx.platform.typedef.pthread_once_t = int
|
81
136
|
rbx.platform.typedef.pthread_t = ulong
|
137
|
+
rbx.platform.typedef.ptrdiff_t = long
|
82
138
|
rbx.platform.typedef.quad_t = long
|
83
139
|
rbx.platform.typedef.register_t = long
|
84
140
|
rbx.platform.typedef.rlim_t = ulong
|
@@ -93,12 +149,27 @@ rbx.platform.typedef.u_char = uchar
|
|
93
149
|
rbx.platform.typedef.u_int = uint
|
94
150
|
rbx.platform.typedef.u_int16_t = ushort
|
95
151
|
rbx.platform.typedef.u_int32_t = uint
|
96
|
-
rbx.platform.typedef.u_int64_t =
|
152
|
+
rbx.platform.typedef.u_int64_t = ulong
|
97
153
|
rbx.platform.typedef.u_int8_t = uchar
|
98
154
|
rbx.platform.typedef.u_long = ulong
|
99
155
|
rbx.platform.typedef.u_quad_t = ulong
|
100
156
|
rbx.platform.typedef.u_short = ushort
|
101
157
|
rbx.platform.typedef.uid_t = uint
|
102
158
|
rbx.platform.typedef.uint = uint
|
159
|
+
rbx.platform.typedef.uint16_t = ushort
|
160
|
+
rbx.platform.typedef.uint32_t = uint
|
161
|
+
rbx.platform.typedef.uint64_t = ulong
|
162
|
+
rbx.platform.typedef.uint8_t = uchar
|
163
|
+
rbx.platform.typedef.uint_fast16_t = ulong
|
164
|
+
rbx.platform.typedef.uint_fast32_t = ulong
|
165
|
+
rbx.platform.typedef.uint_fast64_t = ulong
|
166
|
+
rbx.platform.typedef.uint_fast8_t = uchar
|
167
|
+
rbx.platform.typedef.uint_least16_t = ushort
|
168
|
+
rbx.platform.typedef.uint_least32_t = uint
|
169
|
+
rbx.platform.typedef.uint_least64_t = ulong
|
170
|
+
rbx.platform.typedef.uint_least8_t = uchar
|
171
|
+
rbx.platform.typedef.uintmax_t = ulong
|
172
|
+
rbx.platform.typedef.uintptr_t = ulong
|
103
173
|
rbx.platform.typedef.ulong = ulong
|
104
174
|
rbx.platform.typedef.ushort = ushort
|
175
|
+
rbx.platform.typedef.wchar_t = uint
|
data/lib/ffi/pointer.rb
CHANGED
@@ -45,12 +45,12 @@ module FFI
|
|
45
45
|
SIZE = Platform::ADDRESS_SIZE / 8 unless const_defined?(:SIZE)
|
46
46
|
|
47
47
|
# Return the size of a pointer on the current platform, in bytes
|
48
|
-
# @return [
|
48
|
+
# @return [Integer]
|
49
49
|
def self.size
|
50
50
|
SIZE
|
51
51
|
end unless respond_to?(:size)
|
52
52
|
|
53
|
-
# @param [nil,
|
53
|
+
# @param [nil,Integer] len length of string to return
|
54
54
|
# @return [String]
|
55
55
|
# Read pointer's contents as a string, or the first +len+ bytes of the
|
56
56
|
# equivalent string if +len+ is not +nil+.
|
@@ -63,7 +63,7 @@ module FFI
|
|
63
63
|
end
|
64
64
|
end unless method_defined?(:read_string)
|
65
65
|
|
66
|
-
# @param [
|
66
|
+
# @param [Integer] len length of string to return
|
67
67
|
# @return [String]
|
68
68
|
# Read the first +len+ bytes of pointer's contents as a string.
|
69
69
|
#
|
@@ -83,7 +83,7 @@ module FFI
|
|
83
83
|
end unless method_defined?(:read_string_to_null)
|
84
84
|
|
85
85
|
# @param [String] str string to write
|
86
|
-
# @param [
|
86
|
+
# @param [Integer] len length of string to return
|
87
87
|
# @return [self]
|
88
88
|
# Write +len+ first bytes of +str+ in pointer's contents.
|
89
89
|
#
|
@@ -94,7 +94,7 @@ module FFI
|
|
94
94
|
end unless method_defined?(:write_string_length)
|
95
95
|
|
96
96
|
# @param [String] str string to write
|
97
|
-
# @param [
|
97
|
+
# @param [Integer] len length of string to return
|
98
98
|
# @return [self]
|
99
99
|
# Write +str+ in pointer's contents, or first +len+ bytes if
|
100
100
|
# +len+ is not +nil+.
|
@@ -106,7 +106,7 @@ module FFI
|
|
106
106
|
|
107
107
|
# @param [Type] type type of data to read from pointer's contents
|
108
108
|
# @param [Symbol] reader method to send to +self+ to read +type+
|
109
|
-
# @param [
|
109
|
+
# @param [Integer] length
|
110
110
|
# @return [Array]
|
111
111
|
# Read an array of +type+ of length +length+.
|
112
112
|
# @example
|
data/lib/ffi/struct.rb
CHANGED
@@ -41,12 +41,12 @@ module FFI
|
|
41
41
|
class Struct
|
42
42
|
|
43
43
|
# Get struct size
|
44
|
-
# @return [
|
44
|
+
# @return [Integer]
|
45
45
|
def size
|
46
46
|
self.class.size
|
47
47
|
end
|
48
48
|
|
49
|
-
# @return [
|
49
|
+
# @return [Integer] Struct alignment
|
50
50
|
def alignment
|
51
51
|
self.class.alignment
|
52
52
|
end
|
@@ -87,13 +87,13 @@ module FFI
|
|
87
87
|
end
|
88
88
|
|
89
89
|
# Get struct size
|
90
|
-
# @return [
|
90
|
+
# @return [Integer]
|
91
91
|
def self.size
|
92
92
|
defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0
|
93
93
|
end
|
94
94
|
|
95
95
|
# set struct size
|
96
|
-
# @param [
|
96
|
+
# @param [Integer] size
|
97
97
|
# @return [size]
|
98
98
|
def self.size=(size)
|
99
99
|
raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout)
|
data/lib/ffi/struct_layout.rb
CHANGED
@@ -35,13 +35,13 @@ module FFI
|
|
35
35
|
|
36
36
|
class StructLayout
|
37
37
|
|
38
|
-
# @return [Array<Array(Symbol,
|
38
|
+
# @return [Array<Array(Symbol, Integer)>
|
39
39
|
# Get an array of tuples (field name, offset of the field).
|
40
40
|
def offsets
|
41
41
|
members.map { |m| [ m, self[m].offset ] }
|
42
42
|
end
|
43
43
|
|
44
|
-
# @return [
|
44
|
+
# @return [Integer]
|
45
45
|
# Get the offset of a field.
|
46
46
|
def offset_of(field_name)
|
47
47
|
self[field_name].offset
|
@@ -46,13 +46,13 @@ module FFI
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Set size attribute with +size+ only if +size+ is greater than attribute value.
|
49
|
-
# @param [
|
49
|
+
# @param [Integer] size
|
50
50
|
def size=(size)
|
51
51
|
@size = size if size > @size
|
52
52
|
end
|
53
53
|
|
54
54
|
# Set alignment attribute with +align+ only if it is greater than attribute value.
|
55
|
-
# @param [
|
55
|
+
# @param [Integer] align
|
56
56
|
def alignment=(align)
|
57
57
|
@alignment = align if align > @alignment
|
58
58
|
@min_alignment = align
|
@@ -78,7 +78,7 @@ module FFI
|
|
78
78
|
# @overload packed=(packed) Set alignment and packed attributes to
|
79
79
|
# +packed+.
|
80
80
|
#
|
81
|
-
# @param [
|
81
|
+
# @param [Integer] packed
|
82
82
|
#
|
83
83
|
# @return [packed]
|
84
84
|
# @overload packed=(packed) Set packed attribute.
|
@@ -116,7 +116,7 @@ module FFI
|
|
116
116
|
|
117
117
|
# @param [String, Symbol] name name of the field
|
118
118
|
# @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field
|
119
|
-
# @param [
|
119
|
+
# @param [Integer, nil] offset
|
120
120
|
# @return [self]
|
121
121
|
# Add a field to the builder.
|
122
122
|
# @note Setting +offset+ to +nil+ or +-1+ is equivalent to +0+.
|
@@ -154,7 +154,7 @@ module FFI
|
|
154
154
|
|
155
155
|
# @param name (see #add)
|
156
156
|
# @param type (see #add)
|
157
|
-
# @param [
|
157
|
+
# @param [Integer] count array length
|
158
158
|
# @param offset (see #add)
|
159
159
|
# @return (see #add)
|
160
160
|
# Add an array as a field to the builder.
|
@@ -175,9 +175,9 @@ module FFI
|
|
175
175
|
|
176
176
|
private
|
177
177
|
|
178
|
-
# @param [
|
179
|
-
# @param [
|
180
|
-
# @return [
|
178
|
+
# @param [Integer] offset
|
179
|
+
# @param [Integer] align
|
180
|
+
# @return [Integer]
|
181
181
|
def align(offset, align)
|
182
182
|
align + ((offset - 1) & ~(align - 1));
|
183
183
|
end
|