ffi 1.9.10 → 1.9.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +30 -8
- data/ext/ffi_c/AbstractMemory.c +1 -1
- data/ext/ffi_c/Buffer.c +1 -1
- data/ext/ffi_c/Call.c +12 -25
- data/ext/ffi_c/Call.h +17 -0
- data/ext/ffi_c/Function.c +24 -26
- data/ext/ffi_c/MethodHandle.c +3 -5
- data/ext/ffi_c/Pointer.c +3 -3
- data/ext/ffi_c/Variadic.c +24 -0
- data/ext/ffi_c/compat.h +0 -5
- data/ext/ffi_c/libffi/src/mips/ffi.c +4 -2
- data/ext/ffi_c/rbffi_endian.h +1 -1
- data/ffi.gemspec +1 -1
- data/lib/ffi/autopointer.rb +36 -27
- data/lib/ffi/enum.rb +1 -3
- data/lib/ffi/library.rb +14 -1
- data/lib/ffi/pointer.rb +1 -1
- data/lib/ffi/struct.rb +1 -1
- data/lib/ffi/tools/types_generator.rb +6 -7
- data/lib/ffi/types.rb +8 -4
- data/lib/ffi/version.rb +1 -1
- data/libtest/FunctionTest.c +1 -1
- data/libtest/VariadicTest.c +37 -0
- data/spec/ffi/fixtures/ClosureTest.c +15 -0
- data/spec/ffi/fixtures/FunctionTest.c +88 -4
- data/spec/ffi/fixtures/PipeHelper.h +21 -0
- data/spec/ffi/fixtures/PipeHelperPosix.c +41 -0
- data/spec/ffi/fixtures/PipeHelperWindows.c +72 -0
- data/spec/ffi/function_spec.rb +15 -10
- data/spec/ffi/rbx/attach_function_spec.rb +22 -21
- data/spec/ffi/struct_spec.rb +4 -4
- data/spec/ffi/variadic_spec.rb +19 -0
- metadata +8 -5
@@ -6,14 +6,17 @@
|
|
6
6
|
|
7
7
|
#ifdef _WIN32
|
8
8
|
#include <windows.h>
|
9
|
-
#define sleep(x) Sleep(x)
|
10
9
|
#endif
|
11
10
|
|
12
11
|
#ifndef _WIN32
|
13
12
|
#include <unistd.h>
|
14
13
|
#include <pthread.h>
|
14
|
+
#include <stdarg.h>
|
15
|
+
#include <stdlib.h>
|
15
16
|
#endif
|
16
17
|
|
18
|
+
#include "PipeHelper.h"
|
19
|
+
|
17
20
|
int testAdd(int a, int b)
|
18
21
|
{
|
19
22
|
return a + b;
|
@@ -24,10 +27,79 @@ int testFunctionAdd(int a, int b, int (*f)(int, int))
|
|
24
27
|
return f(a, b);
|
25
28
|
};
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
struct testBlockingData {
|
31
|
+
FD_TYPE pipe1[2];
|
32
|
+
FD_TYPE pipe2[2];
|
29
33
|
};
|
30
34
|
|
35
|
+
struct testBlockingData *testBlockingOpen()
|
36
|
+
{
|
37
|
+
struct testBlockingData *self = malloc(sizeof(struct testBlockingData));
|
38
|
+
|
39
|
+
if( pipeHelperCreatePipe(self->pipe1) == -1 ) return NULL;
|
40
|
+
if( pipeHelperCreatePipe(self->pipe2) == -1 ) return NULL;
|
41
|
+
return self;
|
42
|
+
}
|
43
|
+
|
44
|
+
char testBlockingWR(struct testBlockingData *self, char c) {
|
45
|
+
if( pipeHelperWriteChar(self->pipe1[1], c) != 1)
|
46
|
+
return 0;
|
47
|
+
return pipeHelperReadChar(self->pipe2[0], 10);
|
48
|
+
}
|
49
|
+
|
50
|
+
char testBlockingRW(struct testBlockingData *self, char c) {
|
51
|
+
char d = pipeHelperReadChar(self->pipe1[0], 10);
|
52
|
+
if( pipeHelperWriteChar(self->pipe2[1], c) != 1)
|
53
|
+
return 0;
|
54
|
+
return d;
|
55
|
+
}
|
56
|
+
|
57
|
+
void testBlockingClose(struct testBlockingData *self) {
|
58
|
+
pipeHelperClosePipe(self->pipe1[0]);
|
59
|
+
pipeHelperClosePipe(self->pipe1[1]);
|
60
|
+
pipeHelperClosePipe(self->pipe2[0]);
|
61
|
+
pipeHelperClosePipe(self->pipe2[1]);
|
62
|
+
free(self);
|
63
|
+
}
|
64
|
+
|
65
|
+
static int sum_varargs(va_list args) {
|
66
|
+
char sum = 0;
|
67
|
+
int arg;
|
68
|
+
while ((arg = va_arg(args, int)) != 0) {
|
69
|
+
sum += arg;
|
70
|
+
}
|
71
|
+
va_end(args);
|
72
|
+
return sum;
|
73
|
+
}
|
74
|
+
|
75
|
+
/* Write c to pipe1 and return the value read from pipe2, or 0 if there’s
|
76
|
+
* an error such as a timeout, or if c does not equal the sum of the
|
77
|
+
* zero-terminated list of char arguments. */
|
78
|
+
char testBlockingWRva(struct testBlockingData *self, char c, ...) {
|
79
|
+
va_list args;
|
80
|
+
va_start(args, c);
|
81
|
+
if (sum_varargs(args) != c) {
|
82
|
+
return 0;
|
83
|
+
}
|
84
|
+
|
85
|
+
if( pipeHelperWriteChar(self->pipe1[1], c) != 1)
|
86
|
+
return 0;
|
87
|
+
return pipeHelperReadChar(self->pipe2[0], 10);
|
88
|
+
}
|
89
|
+
|
90
|
+
char testBlockingRWva(struct testBlockingData *self, char c, ...) {
|
91
|
+
va_list args;
|
92
|
+
va_start(args, c);
|
93
|
+
if (sum_varargs(args) != c) {
|
94
|
+
return 0;
|
95
|
+
}
|
96
|
+
|
97
|
+
char d = pipeHelperReadChar(self->pipe1[0], 10);
|
98
|
+
if( pipeHelperWriteChar(self->pipe2[1], c) != 1)
|
99
|
+
return 0;
|
100
|
+
return d;
|
101
|
+
}
|
102
|
+
|
31
103
|
struct async_data {
|
32
104
|
void (*fn)(int);
|
33
105
|
int value;
|
@@ -55,4 +127,16 @@ void testAsyncCallback(void (*fn)(int), int value)
|
|
55
127
|
#else
|
56
128
|
(*fn)(value);
|
57
129
|
#endif
|
58
|
-
}
|
130
|
+
}
|
131
|
+
|
132
|
+
#if defined(_WIN32) && !defined(_WIN64)
|
133
|
+
struct StructUCDP {
|
134
|
+
unsigned char a1;
|
135
|
+
double a2;
|
136
|
+
void *a3;
|
137
|
+
};
|
138
|
+
|
139
|
+
void __stdcall testStdcallManyParams(long *a1, char a2, short int a3, int a4, __int64 a5,
|
140
|
+
struct StructUCDP a6, struct StructUCDP *a7, float a8, double a9) {
|
141
|
+
}
|
142
|
+
#endif
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2015 Lars Kanis. All rights reserved.
|
3
|
+
*
|
4
|
+
* For licensing, see LICENSE.SPECS
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef PIPEHELPER_H
|
8
|
+
#define PIPEHELPER_H
|
9
|
+
|
10
|
+
#ifdef _WIN32
|
11
|
+
#define FD_TYPE HANDLE
|
12
|
+
#else
|
13
|
+
#define FD_TYPE int
|
14
|
+
#endif
|
15
|
+
|
16
|
+
int pipeHelperCreatePipe(FD_TYPE pipefd[2]);
|
17
|
+
char pipeHelperReadChar(FD_TYPE fd, int timeout);
|
18
|
+
int pipeHelperWriteChar(FD_TYPE fd, char c);
|
19
|
+
void pipeHelperClosePipe(FD_TYPE fd);
|
20
|
+
|
21
|
+
#endif
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2015 Lars Kanis. All rights reserved.
|
3
|
+
*
|
4
|
+
* For licensing, see LICENSE.SPECS
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef _WIN32
|
8
|
+
#include <unistd.h>
|
9
|
+
#include <sys/time.h>
|
10
|
+
#include "PipeHelper.h"
|
11
|
+
|
12
|
+
int pipeHelperCreatePipe(FD_TYPE pipefd[2])
|
13
|
+
{
|
14
|
+
return pipe(pipefd);
|
15
|
+
}
|
16
|
+
|
17
|
+
char pipeHelperReadChar(FD_TYPE fd, int timeout)
|
18
|
+
{
|
19
|
+
char d;
|
20
|
+
struct timeval time = {timeout, 0}; // timeout after x seconds
|
21
|
+
fd_set read_fds;
|
22
|
+
FD_ZERO(&read_fds);
|
23
|
+
FD_SET(fd, &read_fds);
|
24
|
+
|
25
|
+
if(select(fd + 1, &read_fds, NULL, NULL, &time) <= 0)
|
26
|
+
return 0;
|
27
|
+
|
28
|
+
if( read(fd, &d, 1) != 1)
|
29
|
+
return 0;
|
30
|
+
return d;
|
31
|
+
}
|
32
|
+
|
33
|
+
int pipeHelperWriteChar(FD_TYPE fd, char c)
|
34
|
+
{
|
35
|
+
return write(fd, &c, 1);
|
36
|
+
}
|
37
|
+
|
38
|
+
void pipeHelperClosePipe(FD_TYPE fd) {
|
39
|
+
close(fd);
|
40
|
+
}
|
41
|
+
#endif
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
|
3
|
+
*
|
4
|
+
* For licensing, see LICENSE.SPECS
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifdef _WIN32
|
8
|
+
#include <windows.h>
|
9
|
+
#include "PipeHelper.h"
|
10
|
+
|
11
|
+
int pipeHelperCreatePipe(FD_TYPE pipefd[2])
|
12
|
+
{
|
13
|
+
char name[ MAX_PATH ];
|
14
|
+
static int pipe_idx = 0;
|
15
|
+
sprintf( name, "\\\\.\\Pipe\\pipeHelper-%u-%i",
|
16
|
+
(unsigned int)GetCurrentProcessId(), pipe_idx++ );
|
17
|
+
|
18
|
+
pipefd[0] = CreateNamedPipe( name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
|
19
|
+
PIPE_TYPE_BYTE | PIPE_WAIT,
|
20
|
+
1, // Number of pipes
|
21
|
+
5, // Out buffer size
|
22
|
+
5, // In buffer size
|
23
|
+
60 * 1000, // Timeout in ms
|
24
|
+
NULL );
|
25
|
+
if(pipefd[0] == INVALID_HANDLE_VALUE)
|
26
|
+
return -1;
|
27
|
+
|
28
|
+
pipefd[1] = CreateFile( name, GENERIC_WRITE, 0, NULL,
|
29
|
+
OPEN_EXISTING,
|
30
|
+
FILE_ATTRIBUTE_NORMAL,
|
31
|
+
NULL);
|
32
|
+
|
33
|
+
if(pipefd[1] == INVALID_HANDLE_VALUE) {
|
34
|
+
CloseHandle( pipefd[0] );
|
35
|
+
return -1;
|
36
|
+
}
|
37
|
+
return 0;
|
38
|
+
}
|
39
|
+
|
40
|
+
char pipeHelperReadChar(FD_TYPE fd, int timeout)
|
41
|
+
{
|
42
|
+
char d;
|
43
|
+
OVERLAPPED ovl;
|
44
|
+
ZeroMemory(&ovl, sizeof(ovl));
|
45
|
+
ovl.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
46
|
+
if( ReadFile(fd, &d, 1, NULL, &ovl) == 0) {
|
47
|
+
DWORD recvd = 0;;
|
48
|
+
DWORD res = WaitForSingleObject(ovl.hEvent, timeout * 1000);
|
49
|
+
if( res != WAIT_OBJECT_0 ) {
|
50
|
+
CloseHandle(ovl.hEvent);
|
51
|
+
return 0;
|
52
|
+
}
|
53
|
+
if( GetOverlappedResult(fd, &ovl, &recvd, FALSE) == 0 ) {
|
54
|
+
CloseHandle(ovl.hEvent);
|
55
|
+
return 0;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
CloseHandle(ovl.hEvent);
|
59
|
+
return d;
|
60
|
+
}
|
61
|
+
|
62
|
+
int pipeHelperWriteChar(FD_TYPE fd, char c)
|
63
|
+
{
|
64
|
+
DWORD written;
|
65
|
+
return WriteFile(fd, &c, 1, &written, NULL) == 0 ? 0 : 1;
|
66
|
+
}
|
67
|
+
|
68
|
+
void pipeHelperClosePipe(FD_TYPE fd) {
|
69
|
+
CloseHandle(fd);
|
70
|
+
}
|
71
|
+
|
72
|
+
#endif
|
data/spec/ffi/function_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe FFI::Function do
|
|
12
12
|
attach_function :testFunctionAdd, [:int, :int, :pointer], :int
|
13
13
|
end
|
14
14
|
before do
|
15
|
-
@libtest = FFI::DynamicLibrary.open(TestLibrary::PATH,
|
15
|
+
@libtest = FFI::DynamicLibrary.open(TestLibrary::PATH,
|
16
16
|
FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
|
17
17
|
end
|
18
18
|
|
@@ -22,7 +22,7 @@ describe FFI::Function do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'raises an error when passing a wrong signature' do
|
25
|
-
expect { FFI::Function.new([], :int).new { } }.to raise_error TypeError
|
25
|
+
expect { FFI::Function.new([], :int).new { } }.to raise_error TypeError
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'returns a native pointer' do
|
@@ -63,15 +63,20 @@ describe FFI::Function do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'can wrap a blocking function' do
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
fpOpen = FFI::Function.new(:pointer, [ ], @libtest.find_function('testBlockingOpen'))
|
67
|
+
fpRW = FFI::Function.new(:char, [ :pointer, :char ], @libtest.find_function('testBlockingRW'), :blocking => true)
|
68
|
+
fpWR = FFI::Function.new(:char, [ :pointer, :char ], @libtest.find_function('testBlockingWR'), :blocking => true)
|
69
|
+
fpClose = FFI::Function.new(:void, [ :pointer ], @libtest.find_function('testBlockingClose'))
|
70
|
+
handle = fpOpen.call
|
71
|
+
expect(handle).not_to be_null
|
72
|
+
begin
|
73
|
+
thWR = Thread.new { fpWR.call(handle, 63) }
|
74
|
+
thRW = Thread.new { fpRW.call(handle, 64) }
|
75
|
+
expect(thWR.value).to eq(64)
|
76
|
+
expect(thRW.value).to eq(63)
|
77
|
+
ensure
|
78
|
+
fpClose.call(handle)
|
73
79
|
end
|
74
|
-
threads.each { |t| t.join }
|
75
80
|
end
|
76
81
|
|
77
82
|
it 'autorelease flag is set to true by default' do
|
@@ -5,29 +5,30 @@
|
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
module LibC
|
13
|
-
extend FFI::Library
|
14
|
-
ffi_lib FFI::Library::LIBC
|
8
|
+
unless FFI::Platform.windows?
|
9
|
+
class Timeval < FFI::Struct
|
10
|
+
layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
13
|
+
module LibC
|
14
|
+
extend FFI::Library
|
15
|
+
ffi_lib FFI::Library::LIBC
|
18
16
|
|
19
|
-
|
20
|
-
it "correctly returns a value for gettimeofday" do
|
21
|
-
t = Timeval.new
|
22
|
-
time = LibC.gettimeofday(t.pointer, nil)
|
23
|
-
expect(time).to be_kind_of(Integer)
|
17
|
+
attach_function :gettimeofday, [:pointer, :pointer], :int
|
24
18
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
19
|
+
|
20
|
+
describe FFI::Library, "#attach_function" do
|
21
|
+
it "correctly returns a value for gettimeofday" do
|
22
|
+
t = Timeval.new
|
23
|
+
time = LibC.gettimeofday(t.pointer, nil)
|
24
|
+
expect(time).to be_kind_of(Integer)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "correctly populates a struct for gettimeofday" do
|
28
|
+
t = Timeval.new
|
29
|
+
LibC.gettimeofday(t.pointer, nil)
|
30
|
+
expect(t[:tv_sec]).to be_kind_of(Numeric)
|
31
|
+
expect(t[:tv_usec]).to be_kind_of(Numeric)
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
|
data/spec/ffi/struct_spec.rb
CHANGED
@@ -7,7 +7,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
|
7
7
|
|
8
8
|
describe "Struct aligns fields correctly" do
|
9
9
|
it "char, followed by an int" do
|
10
|
-
pending("not supported in 1.8") if RUBY_VERSION =~
|
10
|
+
pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
|
11
11
|
class CIStruct < FFI::Struct
|
12
12
|
layout :c => :char, :i => :int
|
13
13
|
end
|
@@ -15,7 +15,7 @@ describe "Struct aligns fields correctly" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "short, followed by an int" do
|
18
|
-
pending("not supported in 1.8") if RUBY_VERSION =~
|
18
|
+
pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
|
19
19
|
class SIStruct < FFI::Struct
|
20
20
|
layout :s => :short, :i => :int
|
21
21
|
end
|
@@ -23,7 +23,7 @@ describe "Struct aligns fields correctly" do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it "int, followed by an int" do
|
26
|
-
pending("not supported in 1.8") if RUBY_VERSION =~
|
26
|
+
pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
|
27
27
|
class IIStruct < FFI::Struct
|
28
28
|
layout :i1 => :int, :i => :int
|
29
29
|
end
|
@@ -31,7 +31,7 @@ describe "Struct aligns fields correctly" do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "long long, followed by an int" do
|
34
|
-
pending("not supported in 1.8") if RUBY_VERSION =~
|
34
|
+
pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
|
35
35
|
class LLIStruct < FFI::Struct
|
36
36
|
layout :l => :long_long, :i => :int
|
37
37
|
end
|
data/spec/ffi/variadic_spec.rb
CHANGED
@@ -13,6 +13,11 @@ describe "Function with variadic arguments" do
|
|
13
13
|
enum :enum_type2, [:c3, 42, :c4]
|
14
14
|
attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
|
15
15
|
attach_function :pack_varargs2, [ :buffer_out, :enum_type1, :string, :varargs ], :enum_type1
|
16
|
+
|
17
|
+
attach_function :testBlockingOpen, [ ], :pointer
|
18
|
+
attach_function :testBlockingRWva, [ :pointer, :char, :varargs ], :char, :blocking => true
|
19
|
+
attach_function :testBlockingWRva, [ :pointer, :char, :varargs ], :char, :blocking => true
|
20
|
+
attach_function :testBlockingClose, [ :pointer ], :void
|
16
21
|
end
|
17
22
|
|
18
23
|
it "takes enum arguments" do
|
@@ -27,6 +32,20 @@ describe "Function with variadic arguments" do
|
|
27
32
|
expect(LibTest.pack_varargs2(buf, :c1, "ii", :int, :c3, :int, :c4)).to eq(:c2)
|
28
33
|
end
|
29
34
|
|
35
|
+
it 'can wrap a blocking function with varargs' do
|
36
|
+
pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
|
37
|
+
handle = LibTest.testBlockingOpen
|
38
|
+
expect(handle).not_to be_null
|
39
|
+
begin
|
40
|
+
thWR = Thread.new { LibTest.testBlockingWRva(handle, 63, :int, 40, :int, 23, :int, 0) }
|
41
|
+
thRW = Thread.new { LibTest.testBlockingRWva(handle, 64, :int, 40, :int, 24, :int, 0) }
|
42
|
+
expect(thWR.value).to eq(64)
|
43
|
+
expect(thRW.value).to eq(63)
|
44
|
+
ensure
|
45
|
+
LibTest.testBlockingClose(handle)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
30
49
|
[ 0, 127, -128, -1 ].each do |i|
|
31
50
|
it "call variadic with (:char (#{i})) argument" do
|
32
51
|
buf = FFI::Buffer.new :long_long
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Meissner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.5.2
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.5.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -513,6 +513,9 @@ files:
|
|
513
513
|
- spec/ffi/fixtures/GlobalVariable.c
|
514
514
|
- spec/ffi/fixtures/LastErrorTest.c
|
515
515
|
- spec/ffi/fixtures/NumberTest.c
|
516
|
+
- spec/ffi/fixtures/PipeHelper.h
|
517
|
+
- spec/ffi/fixtures/PipeHelperPosix.c
|
518
|
+
- spec/ffi/fixtures/PipeHelperWindows.c
|
516
519
|
- spec/ffi/fixtures/PointerTest.c
|
517
520
|
- spec/ffi/fixtures/ReferenceTest.c
|
518
521
|
- spec/ffi/fixtures/StringTest.c
|
@@ -567,7 +570,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
567
570
|
version: '0'
|
568
571
|
requirements: []
|
569
572
|
rubyforge_project:
|
570
|
-
rubygems_version: 2.
|
573
|
+
rubygems_version: 2.5.1
|
571
574
|
signing_key:
|
572
575
|
specification_version: 4
|
573
576
|
summary: Ruby FFI
|