fiddle 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +13 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/fiddle/closure.c +345 -0
- data/ext/fiddle/closure.h +8 -0
- data/ext/fiddle/conversions.c +141 -0
- data/ext/fiddle/conversions.h +44 -0
- data/ext/fiddle/extconf.rb +183 -0
- data/ext/fiddle/extlibs +2 -0
- data/ext/fiddle/fiddle.c +454 -0
- data/ext/fiddle/fiddle.h +138 -0
- data/ext/fiddle/function.c +315 -0
- data/ext/fiddle/function.h +8 -0
- data/ext/fiddle/handle.c +479 -0
- data/ext/fiddle/pointer.c +721 -0
- data/ext/fiddle/win32/fficonfig.h +29 -0
- data/ext/fiddle/win32/libffi-3.2.1-mswin.patch +191 -0
- data/ext/fiddle/win32/libffi-config.rb +48 -0
- data/ext/fiddle/win32/libffi.mk.tmpl +96 -0
- data/fiddle.gemspec +23 -0
- data/lib/fiddle.rb +56 -0
- data/lib/fiddle/closure.rb +49 -0
- data/lib/fiddle/cparser.rb +194 -0
- data/lib/fiddle/function.rb +18 -0
- data/lib/fiddle/import.rb +318 -0
- data/lib/fiddle/pack.rb +129 -0
- data/lib/fiddle/struct.rb +244 -0
- data/lib/fiddle/types.rb +72 -0
- data/lib/fiddle/value.rb +113 -0
- metadata +136 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
#define HAVE_ALLOCA 1
|
2
|
+
#define HAVE_MEMCPY 1
|
3
|
+
#define HAVE_MEMORY_H 1
|
4
|
+
#define HAVE_STDLIB_H 1
|
5
|
+
#define HAVE_STRING_H 1
|
6
|
+
#define HAVE_SYS_STAT_H 1
|
7
|
+
#define HAVE_SYS_TYPES_H 1
|
8
|
+
#if _MSC_VER >= 1600
|
9
|
+
#define HAVE_INTTYPES_H 1
|
10
|
+
#define HAVE_STDINT_H 1
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define SIZEOF_DOUBLE 8
|
14
|
+
#if defined(X86_WIN64)
|
15
|
+
#define SIZEOF_SIZE_T 8
|
16
|
+
#else
|
17
|
+
#define SIZEOF_SIZE_T 4
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#define STACK_DIRECTION -1
|
21
|
+
|
22
|
+
#define STDC_HEADERS 1
|
23
|
+
|
24
|
+
#ifdef LIBFFI_ASM
|
25
|
+
#define FFI_HIDDEN(name)
|
26
|
+
#else
|
27
|
+
#define FFI_HIDDEN
|
28
|
+
#endif
|
29
|
+
|
@@ -0,0 +1,191 @@
|
|
1
|
+
diff -ru libffi-3.2.1/src/x86/ffi.c libffi-3.2.1/src/x86/ffi.c
|
2
|
+
--- libffi-3.2.1/src/x86/ffi.c 2014-11-08 21:47:24.000000000 +0900
|
3
|
+
+++ libffi-3.2.1/src/x86/ffi.c 2014-12-25 18:46:14.806761900 +0900
|
4
|
+
@@ -99,11 +99,13 @@
|
5
|
+
i != 0;
|
6
|
+
i--, p_arg += dir, p_argv += dir)
|
7
|
+
{
|
8
|
+
+ size_t z;
|
9
|
+
+
|
10
|
+
/* Align if necessary */
|
11
|
+
if ((sizeof(void*) - 1) & (size_t) argp)
|
12
|
+
argp = (char *) ALIGN(argp, sizeof(void*));
|
13
|
+
|
14
|
+
- size_t z = (*p_arg)->size;
|
15
|
+
+ z = (*p_arg)->size;
|
16
|
+
|
17
|
+
#ifdef X86_WIN64
|
18
|
+
if (z > FFI_SIZEOF_ARG
|
19
|
+
@@ -202,6 +204,7 @@
|
20
|
+
on top of stack, so that those can be moved to registers by call-handler. */
|
21
|
+
if (stack_args_count > 0)
|
22
|
+
{
|
23
|
+
+ int i;
|
24
|
+
if (dir < 0 && stack_args_count > 1)
|
25
|
+
{
|
26
|
+
/* Reverse order if iterating arguments backwards */
|
27
|
+
@@ -210,7 +213,6 @@
|
28
|
+
*(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp;
|
29
|
+
}
|
30
|
+
|
31
|
+
- int i;
|
32
|
+
for (i = 0; i < stack_args_count; i++)
|
33
|
+
{
|
34
|
+
if (p_stack_data[i] != argp2)
|
35
|
+
@@ -569,11 +571,12 @@
|
36
|
+
i < cif->nargs && passed_regs < max_stack_count;
|
37
|
+
i++, p_arg++)
|
38
|
+
{
|
39
|
+
+ size_t sz;
|
40
|
+
if ((*p_arg)->type == FFI_TYPE_FLOAT
|
41
|
+
|| (*p_arg)->type == FFI_TYPE_STRUCT)
|
42
|
+
continue;
|
43
|
+
|
44
|
+
- size_t sz = (*p_arg)->size;
|
45
|
+
+ sz = (*p_arg)->size;
|
46
|
+
if(sz == 0 || sz > FFI_SIZEOF_ARG)
|
47
|
+
continue;
|
48
|
+
|
49
|
+
@@ -599,11 +602,13 @@
|
50
|
+
i != 0;
|
51
|
+
i--, p_arg += dir, p_argv += dir)
|
52
|
+
{
|
53
|
+
+ size_t z;
|
54
|
+
+
|
55
|
+
/* Align if necessary */
|
56
|
+
if ((sizeof(void*) - 1) & (size_t) argp)
|
57
|
+
argp = (char *) ALIGN(argp, sizeof(void*));
|
58
|
+
|
59
|
+
- size_t z = (*p_arg)->size;
|
60
|
+
+ z = (*p_arg)->size;
|
61
|
+
|
62
|
+
#ifdef X86_WIN64
|
63
|
+
if (z > FFI_SIZEOF_ARG
|
64
|
+
@@ -642,7 +647,7 @@
|
65
|
+
#endif
|
66
|
+
}
|
67
|
+
|
68
|
+
- return (size_t)argp - (size_t)stack;
|
69
|
+
+ return (int)((size_t)argp - (size_t)stack);
|
70
|
+
}
|
71
|
+
|
72
|
+
#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
|
73
|
+
@@ -855,11 +860,12 @@
|
74
|
+
|
75
|
+
for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++)
|
76
|
+
{
|
77
|
+
+ size_t sz;
|
78
|
+
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|
79
|
+
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
|
80
|
+
continue;
|
81
|
+
|
82
|
+
- size_t sz = cif->arg_types[i]->size;
|
83
|
+
+ sz = cif->arg_types[i]->size;
|
84
|
+
if (sz == 0 || sz > FFI_SIZEOF_ARG)
|
85
|
+
continue;
|
86
|
+
|
87
|
+
diff -ru libffi-3.2.1/src/x86/ffitarget.h libffi-3.2.1/src/x86/ffitarget.h
|
88
|
+
--- libffi-3.2.1/src/x86/ffitarget.h 2014-11-08 21:47:24.000000000 +0900
|
89
|
+
+++ libffi-3.2.1/src/x86/ffitarget.h 2014-12-22 15:45:54.000000000 +0900
|
90
|
+
@@ -50,7 +50,9 @@
|
91
|
+
#endif
|
92
|
+
|
93
|
+
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
94
|
+
+#ifndef _MSC_VER
|
95
|
+
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
96
|
+
+#endif
|
97
|
+
|
98
|
+
/* ---- Generic type definitions ----------------------------------------- */
|
99
|
+
|
100
|
+
diff -ru libffi-3.2.1/src/x86/win64.S libffi-3.2.1/src/x86/win64.S
|
101
|
+
--- libffi-3.2.1/src/x86/win64.S 2014-11-08 21:47:24.000000000 +0900
|
102
|
+
+++ libffi-3.2.1/src/x86/win64.S 2014-12-22 16:14:40.000000000 +0900
|
103
|
+
@@ -127,7 +127,7 @@
|
104
|
+
|
105
|
+
mov rcx, QWORD PTR RVALUE[rbp]
|
106
|
+
mov DWORD PTR [rcx], eax
|
107
|
+
- jmp ret_void$
|
108
|
+
+ jmp SHORT ret_void$
|
109
|
+
|
110
|
+
ret_struct2b$:
|
111
|
+
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B
|
112
|
+
@@ -135,7 +135,7 @@
|
113
|
+
|
114
|
+
mov rcx, QWORD PTR RVALUE[rbp]
|
115
|
+
mov WORD PTR [rcx], ax
|
116
|
+
- jmp ret_void$
|
117
|
+
+ jmp SHORT ret_void$
|
118
|
+
|
119
|
+
ret_struct1b$:
|
120
|
+
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B
|
121
|
+
@@ -143,7 +143,7 @@
|
122
|
+
|
123
|
+
mov rcx, QWORD PTR RVALUE[rbp]
|
124
|
+
mov BYTE PTR [rcx], al
|
125
|
+
- jmp ret_void$
|
126
|
+
+ jmp SHORT ret_void$
|
127
|
+
|
128
|
+
ret_uint8$:
|
129
|
+
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8
|
130
|
+
@@ -152,7 +152,7 @@
|
131
|
+
mov rcx, QWORD PTR RVALUE[rbp]
|
132
|
+
movzx rax, al
|
133
|
+
mov QWORD PTR [rcx], rax
|
134
|
+
- jmp ret_void$
|
135
|
+
+ jmp SHORT ret_void$
|
136
|
+
|
137
|
+
ret_sint8$:
|
138
|
+
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8
|
139
|
+
@@ -161,7 +161,7 @@
|
140
|
+
mov rcx, QWORD PTR RVALUE[rbp]
|
141
|
+
movsx rax, al
|
142
|
+
mov QWORD PTR [rcx], rax
|
143
|
+
- jmp ret_void$
|
144
|
+
+ jmp SHORT ret_void$
|
145
|
+
|
146
|
+
ret_uint16$:
|
147
|
+
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16
|
148
|
+
@@ -188,7 +188,13 @@
|
149
|
+
mov rcx, QWORD PTR RVALUE[rbp]
|
150
|
+
mov eax, eax
|
151
|
+
mov QWORD PTR [rcx], rax
|
152
|
+
- jmp SHORT ret_void$
|
153
|
+
+
|
154
|
+
+ret_void$:
|
155
|
+
+ xor rax, rax
|
156
|
+
+
|
157
|
+
+ lea rsp, QWORD PTR [rbp+16]
|
158
|
+
+ pop rbp
|
159
|
+
+ ret 0
|
160
|
+
|
161
|
+
ret_sint32$:
|
162
|
+
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32
|
163
|
+
@@ -247,13 +253,6 @@
|
164
|
+
cdqe
|
165
|
+
mov QWORD PTR [rcx], rax
|
166
|
+
jmp SHORT ret_void$
|
167
|
+
-
|
168
|
+
-ret_void$:
|
169
|
+
- xor rax, rax
|
170
|
+
-
|
171
|
+
- lea rsp, QWORD PTR [rbp+16]
|
172
|
+
- pop rbp
|
173
|
+
- ret 0
|
174
|
+
ffi_call_win64 ENDP
|
175
|
+
_TEXT ENDS
|
176
|
+
END
|
177
|
+
diff -ru libffi-3.2.1/include/ffi.h.in libffi-3.2.1/include/ffi.h.in
|
178
|
+
--- libffi-3.2.1/include/ffi.h.in 2014-11-08 21:47:24.000000000 +0900
|
179
|
+
+++ libffi-3.2.1/include/ffi.h.in 2015-01-11 12:35:30.000000000 +0900
|
180
|
+
@@ -103,6 +103,11 @@
|
181
|
+
# undef FFI_64_BIT_MAX
|
182
|
+
# define FFI_64_BIT_MAX 9223372036854775807LL
|
183
|
+
# endif
|
184
|
+
+# ifdef _MSC_VER
|
185
|
+
+# define FFI_LONG_LONG_MAX _I64_MAX
|
186
|
+
+# undef FFI_64_BIT_MAX
|
187
|
+
+# define FFI_64_BIT_MAX 9223372036854775807I64
|
188
|
+
+# endif
|
189
|
+
# endif
|
190
|
+
#endif
|
191
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# frozen_string_literal: false
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
basedir = File.dirname(__FILE__)
|
6
|
+
conf = {}
|
7
|
+
enable = {}
|
8
|
+
until ARGV.empty?
|
9
|
+
arg = ARGV.shift
|
10
|
+
case arg
|
11
|
+
when '-C'
|
12
|
+
# ignore
|
13
|
+
when /\A--srcdir=(.*)/
|
14
|
+
conf['SRCDIR'] = srcdir = $1
|
15
|
+
when /\A(CC|CFLAGS|CXX|CXXFLAGS|LD|LDFLAGS)=(.*)/
|
16
|
+
conf[$1] = $2
|
17
|
+
when /\A--host=(.*)/
|
18
|
+
host = $1
|
19
|
+
when /\A--enable-([^=]+)(?:=(.*))?/
|
20
|
+
enable[$1] = $2 || true
|
21
|
+
when /\A--disable-([^=]+)/
|
22
|
+
enable[$1] = false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
IO.foreach("#{srcdir}/configure.ac") do |line|
|
27
|
+
if /^AC_INIT\((.*)\)/ =~ line
|
28
|
+
version = $1.split(/,\s*/)[1]
|
29
|
+
version.gsub!(/\A\[|\]\z/, '')
|
30
|
+
conf['VERSION'] = version
|
31
|
+
break
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
builddir = srcdir == "." ? enable['builddir'] : "."
|
36
|
+
conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
|
37
|
+
|
38
|
+
FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])
|
39
|
+
FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true)
|
40
|
+
|
41
|
+
hdr = IO.binread("#{srcdir}/include/ffi.h.in")
|
42
|
+
hdr.gsub!(/@(\w+)@/) {conf[$1] || $&}
|
43
|
+
hdr.gsub!(/^(#if\s+)@\w+@/, '\10')
|
44
|
+
IO.binwrite("#{builddir}/include/ffi.h", hdr)
|
45
|
+
|
46
|
+
mk = IO.binread("#{basedir}/libffi.mk.tmpl")
|
47
|
+
mk.gsub!(/@(\w+)@/) {conf[$1] || $&}
|
48
|
+
IO.binwrite("Makefile", mk)
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# -*- makefile -*-
|
2
|
+
# ====================================================================
|
3
|
+
#
|
4
|
+
# libffi Windows Makefile
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# ====================================================================
|
8
|
+
#
|
9
|
+
NAME = ffi
|
10
|
+
TARGET = @TARGET@
|
11
|
+
CC = cl
|
12
|
+
!if "$(TARGET)" == "X86_WIN64"
|
13
|
+
AS = ml64
|
14
|
+
!else
|
15
|
+
AS = ml
|
16
|
+
!endif
|
17
|
+
AR = link
|
18
|
+
DLEXT = dll
|
19
|
+
OBJEXT = obj
|
20
|
+
LIBEXT = lib
|
21
|
+
TOPDIR = @SRCDIR@
|
22
|
+
CPP = $(CC) -EP
|
23
|
+
CFLAGS = @CFLAGS@
|
24
|
+
ARFLAGS = -lib
|
25
|
+
ASFLAGS = -coff -W3 -Cx
|
26
|
+
INCLUDES= -I. -I./include -I./src/x86 \
|
27
|
+
-I$(TOPDIR)/include -I$(TOPDIR)/include/src/x86
|
28
|
+
|
29
|
+
SRCDIR = $(TOPDIR)/src
|
30
|
+
WORKDIR = ./.libs
|
31
|
+
BUILDDIR= ./src
|
32
|
+
LIBNAME = lib$(NAME)
|
33
|
+
STATICLIB= $(WORKDIR)/$(LIBNAME)_convenience.$(LIBEXT)
|
34
|
+
|
35
|
+
HEADERS = \
|
36
|
+
./fficonfig.h
|
37
|
+
FFI_HEADERS = \
|
38
|
+
./include/ffi.h \
|
39
|
+
./include/ffitarget.h
|
40
|
+
|
41
|
+
!if "$(TARGET)" == "X86_WIN32"
|
42
|
+
OSSRC = win32
|
43
|
+
!else if "$(TARGET)" == "X86_WIN64"
|
44
|
+
OSSRC = win64
|
45
|
+
!else
|
46
|
+
! error unknown target: $(TARGET)
|
47
|
+
!endif
|
48
|
+
|
49
|
+
OBJECTS = \
|
50
|
+
$(BUILDDIR)/closures.$(OBJEXT) \
|
51
|
+
$(BUILDDIR)/debug.$(OBJEXT) \
|
52
|
+
$(BUILDDIR)/java_raw_api.$(OBJEXT) \
|
53
|
+
$(BUILDDIR)/prep_cif.$(OBJEXT) \
|
54
|
+
$(BUILDDIR)/raw_api.$(OBJEXT) \
|
55
|
+
$(BUILDDIR)/types.$(OBJEXT) \
|
56
|
+
$(BUILDDIR)/x86/ffi.$(OBJEXT) \
|
57
|
+
$(BUILDDIR)/x86/$(OSSRC).$(OBJEXT)
|
58
|
+
ASMSRCS = \
|
59
|
+
$(BUILDDIR)/x86/$(OSSRC).asm
|
60
|
+
|
61
|
+
.SUFFIXES : .S .asm
|
62
|
+
|
63
|
+
all: $(WORKDIR) $(STATICLIB)
|
64
|
+
|
65
|
+
{$(SRCDIR)}.c{$(BUILDDIR)}.$(OBJEXT):
|
66
|
+
$(CC) -c $(CFLAGS) $(INCLUDES) -Fo$(@:\=/) -Fd$(WORKDIR)/$(NAME)-src $(<:\=/)
|
67
|
+
|
68
|
+
{$(SRCDIR)/x86}.c{$(BUILDDIR)/x86}.$(OBJEXT):
|
69
|
+
$(CC) -c $(CFLAGS) $(INCLUDES) -Fo$(@:\=/) -Fd$(WORKDIR)/$(NAME)-src $(<:\=/)
|
70
|
+
|
71
|
+
{$(SRCDIR)/x86}.S{$(BUILDDIR)/x86}.asm:
|
72
|
+
$(CPP) $(CFLAGS) $(INCLUDES) $(<:\=/) >$(@:\=/)
|
73
|
+
|
74
|
+
{$(BUILDDIR)/x86}.asm{$(BUILDDIR)/x86}.$(OBJEXT):
|
75
|
+
cd $(@D) && $(AS) -c $(ASFLAGS) -Fo $(@F) $(<F)
|
76
|
+
|
77
|
+
$(BUILDDIR)/x86/$(OSSRC).asm: $(SRCDIR)/x86/$(OSSRC).S
|
78
|
+
|
79
|
+
$(OBJECTS): $(FFI_HEADERS) $(HEADERS)
|
80
|
+
|
81
|
+
$(WORKDIR):
|
82
|
+
-@if not exist "$(WORKDIR:/=\)\$(NULL)" mkdir $(WORKDIR:/=\)
|
83
|
+
|
84
|
+
$(STATICLIB): $(WORKDIR) $(OBJECTS)
|
85
|
+
$(AR) $(ARFLAGS) -out:$(STATICLIB) @<<
|
86
|
+
$(OBJECTS)
|
87
|
+
<<
|
88
|
+
|
89
|
+
clean:
|
90
|
+
-@del /Q $(OBJECTS:/=\) 2>NUL
|
91
|
+
-@del /Q $(ASMSRCS:/=\) 2>NUL
|
92
|
+
-@del /Q /S $(WORKDIR:/=\) 2>NUL
|
93
|
+
|
94
|
+
distclean: clean
|
95
|
+
-@del /Q $(HEADERS:/=\) $(FFI_HEADERS:/=\) 2>NUL
|
96
|
+
-@del /Q Makefile 2>NUL
|
data/fiddle.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "fiddle"
|
3
|
+
spec.version = '1.0.0.beta1'
|
4
|
+
spec.authors = ["Aaron Patterson", "SHIBATA Hiroshi"]
|
5
|
+
spec.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org"]
|
6
|
+
|
7
|
+
spec.summary = %q{A libffi wrapper for Ruby.}
|
8
|
+
spec.description = %q{A libffi wrapper for Ruby.}
|
9
|
+
spec.homepage = "https://github.com/ruby/fiddle"
|
10
|
+
spec.license = "MIT"
|
11
|
+
|
12
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
13
|
+
f.match(%r{^(test|spec|features)/})
|
14
|
+
end
|
15
|
+
spec.bindir = "exe"
|
16
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler"
|
20
|
+
spec.add_development_dependency "rake"
|
21
|
+
spec.add_development_dependency "minitest", "~> 4.0"
|
22
|
+
spec.add_development_dependency "rake-compiler"
|
23
|
+
end
|
data/lib/fiddle.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
require 'fiddle.so'
|
3
|
+
require 'fiddle/function'
|
4
|
+
require 'fiddle/closure'
|
5
|
+
|
6
|
+
module Fiddle
|
7
|
+
if WINDOWS
|
8
|
+
# Returns the last win32 +Error+ of the current executing +Thread+ or nil
|
9
|
+
# if none
|
10
|
+
def self.win32_last_error
|
11
|
+
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__]
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sets the last win32 +Error+ of the current executing +Thread+ to +error+
|
15
|
+
def self.win32_last_error= error
|
16
|
+
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the last +Error+ of the current executing +Thread+ or nil if none
|
21
|
+
def self.last_error
|
22
|
+
Thread.current[:__FIDDLE_LAST_ERROR__]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Sets the last +Error+ of the current executing +Thread+ to +error+
|
26
|
+
def self.last_error= error
|
27
|
+
Thread.current[:__DL2_LAST_ERROR__] = error
|
28
|
+
Thread.current[:__FIDDLE_LAST_ERROR__] = error
|
29
|
+
end
|
30
|
+
|
31
|
+
# call-seq: dlopen(library) => Fiddle::Handle
|
32
|
+
#
|
33
|
+
# Creates a new handler that opens +library+, and returns an instance of
|
34
|
+
# Fiddle::Handle.
|
35
|
+
#
|
36
|
+
# If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which
|
37
|
+
# is the equivalent to RTLD_DEFAULT. See <code>man 3 dlopen</code> for more.
|
38
|
+
#
|
39
|
+
# lib = Fiddle.dlopen(nil)
|
40
|
+
#
|
41
|
+
# The default is dependent on OS, and provide a handle for all libraries
|
42
|
+
# already loaded. For example, in most cases you can use this to access
|
43
|
+
# +libc+ functions, or ruby functions like +rb_str_new+.
|
44
|
+
#
|
45
|
+
# See Fiddle::Handle.new for more.
|
46
|
+
def dlopen library
|
47
|
+
Fiddle::Handle.new library
|
48
|
+
end
|
49
|
+
module_function :dlopen
|
50
|
+
|
51
|
+
# Add constants for backwards compat
|
52
|
+
|
53
|
+
RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc:
|
54
|
+
RTLD_LAZY = Handle::RTLD_LAZY # :nodoc:
|
55
|
+
RTLD_NOW = Handle::RTLD_NOW # :nodoc:
|
56
|
+
end
|