ffi 0.6.2 → 0.6.3
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.
- data/Rakefile +2 -1
- data/ext/ffi_c/Call.c +3 -3
- data/ext/ffi_c/Function.c +3 -2
- data/ext/ffi_c/Struct.c +88 -13
- data/ext/ffi_c/Types.c +1 -1
- data/ext/ffi_c/libffi.mk +1 -1
- data/ext/ffi_c/libffi/configure +1 -1
- data/gen/Rakefile +4 -2
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/library.rb +2 -2
- data/spec/ffi/struct_spec.rb +18 -0
- metadata +2 -14
- data/lib/ffi_c.so +0 -0
data/Rakefile
CHANGED
@@ -75,7 +75,7 @@ PROJ.name = 'ffi'
|
|
75
75
|
PROJ.authors = 'Wayne Meissner'
|
76
76
|
PROJ.email = 'wmeissner@gmail.com'
|
77
77
|
PROJ.url = 'http://wiki.github.com/ffi/ffi'
|
78
|
-
PROJ.version = '0.6.
|
78
|
+
PROJ.version = '0.6.3'
|
79
79
|
PROJ.rubyforge.name = 'ffi'
|
80
80
|
PROJ.readme_file = 'README.rdoc'
|
81
81
|
|
@@ -147,6 +147,7 @@ task :distclean => :clobber do
|
|
147
147
|
FileUtils.rm_rf(Dir["lib/**/ffi_c.#{Config::CONFIG['DLEXT']}"])
|
148
148
|
FileUtils.rm_rf('lib/1.8')
|
149
149
|
FileUtils.rm_rf('lib/1.9')
|
150
|
+
FileUtils.rm_rf('lib/ffi/types.conf')
|
150
151
|
FileUtils.rm_rf('conftest.dSYM')
|
151
152
|
FileUtils.rm_rf('pkg')
|
152
153
|
end
|
data/ext/ffi_c/Call.c
CHANGED
@@ -142,10 +142,10 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, NativeType* paramTy
|
|
142
142
|
|
143
143
|
case NATIVE_BOOL:
|
144
144
|
if (type != T_TRUE && type != T_FALSE) {
|
145
|
-
rb_raise(rb_eTypeError, "
|
145
|
+
rb_raise(rb_eTypeError, "wrong argument type (expected a boolean parameter)");
|
146
146
|
}
|
147
|
-
param->
|
148
|
-
ADJ(param,
|
147
|
+
param->s8 = argv[argidx++] == Qtrue;
|
148
|
+
ADJ(param, INT8);
|
149
149
|
break;
|
150
150
|
|
151
151
|
|
data/ext/ffi_c/Function.c
CHANGED
@@ -374,7 +374,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
374
374
|
param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
|
375
375
|
break;
|
376
376
|
case NATIVE_BOOL:
|
377
|
-
param = (*(
|
377
|
+
param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
|
378
378
|
break;
|
379
379
|
|
380
380
|
case NATIVE_FUNCTION:
|
@@ -428,8 +428,9 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
428
428
|
*((void **) retval) = NULL;
|
429
429
|
}
|
430
430
|
break;
|
431
|
+
|
431
432
|
case NATIVE_BOOL:
|
432
|
-
*((
|
433
|
+
*((ffi_arg *) retval) = rbReturnValue == Qtrue;
|
433
434
|
break;
|
434
435
|
|
435
436
|
case NATIVE_FUNCTION:
|
data/ext/ffi_c/Struct.c
CHANGED
@@ -71,6 +71,8 @@ typedef struct InlineArray_ {
|
|
71
71
|
static void struct_mark(Struct *);
|
72
72
|
static void struct_layout_builder_mark(StructLayoutBuilder *);
|
73
73
|
static void struct_layout_builder_free(StructLayoutBuilder *);
|
74
|
+
static VALUE struct_class_layout(VALUE klass);
|
75
|
+
static void struct_malloc(Struct* s);
|
74
76
|
static void inline_array_mark(InlineArray *);
|
75
77
|
|
76
78
|
static inline int align(int offset, int align);
|
@@ -116,10 +118,8 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
|
|
116
118
|
/* Call up into ruby code to adjust the layout */
|
117
119
|
if (nargs > 1) {
|
118
120
|
s->rbLayout = rb_funcall2(CLASS_OF(self), id_layout, RARRAY_LEN(rest), RARRAY_PTR(rest));
|
119
|
-
} else if (rb_cvar_defined(klass, id_layout_ivar)) {
|
120
|
-
s->rbLayout = rb_cvar_get(klass, id_layout_ivar);
|
121
121
|
} else {
|
122
|
-
|
122
|
+
s->rbLayout = struct_class_layout(klass);
|
123
123
|
}
|
124
124
|
|
125
125
|
if (!rb_obj_is_kind_of(s->rbLayout, rbffi_StructLayoutClass)) {
|
@@ -132,13 +132,74 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
|
|
132
132
|
s->pointer = MEMORY(rbPointer);
|
133
133
|
s->rbPointer = rbPointer;
|
134
134
|
} else {
|
135
|
-
|
136
|
-
s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
|
135
|
+
struct_malloc(s);
|
137
136
|
}
|
138
137
|
|
139
138
|
return self;
|
140
139
|
}
|
141
140
|
|
141
|
+
static VALUE
|
142
|
+
struct_class_layout(VALUE klass)
|
143
|
+
{
|
144
|
+
VALUE layout;
|
145
|
+
if (!rb_cvar_defined(klass, id_layout_ivar)) {
|
146
|
+
rb_raise(rb_eRuntimeError, "no Struct layout configured for %s", rb_class2name(klass));
|
147
|
+
}
|
148
|
+
|
149
|
+
layout = rb_cvar_get(klass, id_layout_ivar);
|
150
|
+
if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
|
151
|
+
rb_raise(rb_eRuntimeError, "invalid Struct layout for %s", rb_class2name(klass));
|
152
|
+
}
|
153
|
+
|
154
|
+
return layout;
|
155
|
+
}
|
156
|
+
|
157
|
+
static StructLayout*
|
158
|
+
struct_layout(VALUE self)
|
159
|
+
{
|
160
|
+
Struct* s = (Struct *) DATA_PTR(self);
|
161
|
+
if (s->layout != NULL) {
|
162
|
+
return s->layout;
|
163
|
+
}
|
164
|
+
|
165
|
+
if (s->layout == NULL) {
|
166
|
+
s->rbLayout = struct_class_layout(CLASS_OF(self));
|
167
|
+
Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
|
168
|
+
}
|
169
|
+
|
170
|
+
return s->layout;
|
171
|
+
}
|
172
|
+
|
173
|
+
static Struct*
|
174
|
+
struct_validate(VALUE self)
|
175
|
+
{
|
176
|
+
Struct* s;
|
177
|
+
Data_Get_Struct(self, Struct, s);
|
178
|
+
|
179
|
+
if (struct_layout(self) == NULL) {
|
180
|
+
rb_raise(rb_eRuntimeError, "struct layout == null");
|
181
|
+
}
|
182
|
+
|
183
|
+
if (s->pointer == NULL) {
|
184
|
+
struct_malloc(s);
|
185
|
+
}
|
186
|
+
|
187
|
+
return s;
|
188
|
+
}
|
189
|
+
|
190
|
+
static void
|
191
|
+
struct_malloc(Struct* s)
|
192
|
+
{
|
193
|
+
if (s->rbPointer == Qnil) {
|
194
|
+
s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
|
195
|
+
|
196
|
+
} else if (!rb_obj_is_kind_of(s->rbPointer, rbffi_AbstractMemoryClass)) {
|
197
|
+
rb_raise(rb_eRuntimeError, "invalid pointer in struct");
|
198
|
+
}
|
199
|
+
|
200
|
+
s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
|
201
|
+
}
|
202
|
+
|
142
203
|
static void
|
143
204
|
struct_mark(Struct *s)
|
144
205
|
{
|
@@ -151,9 +212,6 @@ struct_field(Struct* s, VALUE fieldName)
|
|
151
212
|
{
|
152
213
|
StructLayout* layout = s->layout;
|
153
214
|
VALUE rbField;
|
154
|
-
if (layout == NULL) {
|
155
|
-
rb_raise(rb_eRuntimeError, "layout not set for Struct");
|
156
|
-
}
|
157
215
|
|
158
216
|
rbField = rb_hash_aref(layout->rbFieldMap, fieldName);
|
159
217
|
if (rbField == Qnil) {
|
@@ -170,8 +228,9 @@ struct_aref(VALUE self, VALUE fieldName)
|
|
170
228
|
Struct* s;
|
171
229
|
VALUE rbField;
|
172
230
|
StructField* f;
|
173
|
-
|
174
|
-
|
231
|
+
|
232
|
+
s = struct_validate(self);
|
233
|
+
|
175
234
|
rbField = struct_field(s, fieldName);
|
176
235
|
f = (StructField *) DATA_PTR(rbField);
|
177
236
|
|
@@ -196,7 +255,8 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
|
|
196
255
|
StructField* f;
|
197
256
|
|
198
257
|
|
199
|
-
|
258
|
+
s = struct_validate(self);
|
259
|
+
|
200
260
|
rbField = struct_field(s, fieldName);
|
201
261
|
f = (StructField *) DATA_PTR(rbField);
|
202
262
|
if (f->put != NULL) {
|
@@ -221,12 +281,25 @@ static VALUE
|
|
221
281
|
struct_set_pointer(VALUE self, VALUE pointer)
|
222
282
|
{
|
223
283
|
Struct* s;
|
284
|
+
StructLayout* layout;
|
285
|
+
AbstractMemory* memory;
|
224
286
|
|
225
287
|
if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
|
226
|
-
rb_raise(
|
288
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected Pointer or Buffer)",
|
289
|
+
rb_obj_classname(pointer));
|
290
|
+
return Qnil;
|
227
291
|
}
|
228
292
|
|
293
|
+
|
229
294
|
Data_Get_Struct(self, Struct, s);
|
295
|
+
Data_Get_Struct(pointer, AbstractMemory, memory);
|
296
|
+
layout = struct_layout(self);
|
297
|
+
|
298
|
+
if (layout->base.ffiType->size > memory->size) {
|
299
|
+
rb_raise(rb_eArgError, "memory of %d bytes too small for struct %s (expected at least %d)",
|
300
|
+
memory->size, rb_obj_classname(self), layout->base.ffiType->size);
|
301
|
+
}
|
302
|
+
|
230
303
|
s->pointer = MEMORY(pointer);
|
231
304
|
s->rbPointer = pointer;
|
232
305
|
rb_ivar_set(self, id_pointer_ivar, pointer);
|
@@ -251,7 +324,9 @@ struct_set_layout(VALUE self, VALUE layout)
|
|
251
324
|
Data_Get_Struct(self, Struct, s);
|
252
325
|
|
253
326
|
if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
|
254
|
-
rb_raise(
|
327
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
328
|
+
rb_obj_classname(layout), rb_class2name(rbffi_StructLayoutClass));
|
329
|
+
return Qnil;
|
255
330
|
}
|
256
331
|
|
257
332
|
Data_Get_Struct(layout, StructLayout, s->layout);
|
data/ext/ffi_c/Types.c
CHANGED
@@ -76,7 +76,7 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr, VALUE enums)
|
|
76
76
|
case NATIVE_POINTER:
|
77
77
|
return rbffi_Pointer_NewInstance(*(void **) ptr);
|
78
78
|
case NATIVE_BOOL:
|
79
|
-
return ((
|
79
|
+
return ((unsigned char) *(ffi_arg *) ptr) ? Qtrue : Qfalse;
|
80
80
|
case NATIVE_ENUM:
|
81
81
|
return rb_funcall(rbType, id_find, 1, INT2NUM((unsigned int) *(ffi_arg *) ptr));
|
82
82
|
|
data/ext/ffi_c/libffi.mk
CHANGED
@@ -7,7 +7,7 @@ $(LIBFFI):
|
|
7
7
|
@if [ ! -f $(LIBFFI_BUILD_DIR)/Makefile ]; then \
|
8
8
|
echo "Configuring libffi"; \
|
9
9
|
cd $(LIBFFI_BUILD_DIR) && \
|
10
|
-
/usr/bin/env
|
10
|
+
/usr/bin/env CFLAGS="$(LIBFFI_CFLAGS)" \
|
11
11
|
/bin/sh $(LIBFFI_CONFIGURE) $(LIBFFI_HOST) > /dev/null; \
|
12
12
|
fi
|
13
13
|
cd $(LIBFFI_BUILD_DIR) && $(MAKE)
|
data/ext/ffi_c/libffi/configure
CHANGED
@@ -9021,7 +9021,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
|
|
9021
9021
|
old_archive_from_new_cmds='true'
|
9022
9022
|
# FIXME: Should let the user specify the lib program.
|
9023
9023
|
old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
|
9024
|
-
fix_srcfile_path='`cygpath -w "$srcfile"`'
|
9024
|
+
# fix_srcfile_path='`cygpath -w "$srcfile"`'
|
9025
9025
|
enable_shared_with_static_runtimes=yes
|
9026
9026
|
;;
|
9027
9027
|
|
data/gen/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require "#{File.join(
|
3
|
-
types_conf = File.join(
|
2
|
+
require "#{File.join(File.dirname(__FILE__), '..', 'lib', 'ffi', 'tools', 'types_generator.rb')}"
|
3
|
+
types_conf = File.join(File.dirname(__FILE__), '..', 'lib', 'ffi', 'types.conf')
|
4
|
+
|
4
5
|
file types_conf do |task|
|
5
6
|
options = {}
|
6
7
|
FileUtils.mkdir_p(File.dirname(task.name), { :mode => 0755 })
|
@@ -8,5 +9,6 @@ file types_conf do |task|
|
|
8
9
|
f.puts FFI::TypesGenerator.generate(options)
|
9
10
|
end
|
10
11
|
end
|
12
|
+
|
11
13
|
task :default => types_conf do
|
12
14
|
end
|
data/lib/ffi/ffi.rb
CHANGED
@@ -57,6 +57,7 @@ module FFI
|
|
57
57
|
|
58
58
|
def self.map_library_name(lib)
|
59
59
|
# Mangle the library name to reflect the native library naming conventions
|
60
|
+
lib = lib.to_s unless lib.kind_of?(String)
|
60
61
|
lib = Platform::LIBC if Platform::IS_LINUX && lib == 'c'
|
61
62
|
if lib && File.basename(lib) == lib
|
62
63
|
ext = ".#{Platform::LIBSUFFIX}"
|
data/lib/ffi/library.rb
CHANGED
@@ -42,7 +42,7 @@ module FFI
|
|
42
42
|
|
43
43
|
ffi_libs = names.map do |name|
|
44
44
|
if name == FFI::CURRENT_PROCESS
|
45
|
-
FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::
|
45
|
+
FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
|
46
46
|
else
|
47
47
|
libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
|
48
48
|
lib = nil
|
@@ -50,7 +50,7 @@ module FFI
|
|
50
50
|
|
51
51
|
libnames.each do |libname|
|
52
52
|
begin
|
53
|
-
lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::
|
53
|
+
lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
|
54
54
|
break if lib
|
55
55
|
rescue Exception => ex
|
56
56
|
errors[libname] = ex
|
data/spec/ffi/struct_spec.rb
CHANGED
@@ -133,6 +133,24 @@ describe "Struct tests" do
|
|
133
133
|
mp.get_int64(ll_off).should == 0xfee1deadbeef
|
134
134
|
end
|
135
135
|
end
|
136
|
+
|
137
|
+
it "subclass overrides initialize without calling super" do
|
138
|
+
class InitializeWithoutSuper < FFI::Struct
|
139
|
+
layout :a, :int, :b, :long_long, :d, [:double, 2]
|
140
|
+
|
141
|
+
def initialize(a, b)
|
142
|
+
self[:a] = a
|
143
|
+
self[:b] = b
|
144
|
+
self[:d][0] = 1.2
|
145
|
+
self[:d][1] = 3.4
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
s = InitializeWithoutSuper.new(0x1eefbeef, 0xdeadcafebabe)
|
150
|
+
s[:a].should == 0x1eefbeef
|
151
|
+
s[:b].should == 0xdeadcafebabe
|
152
|
+
end
|
153
|
+
|
136
154
|
it "Can use Struct subclass as parameter type" do
|
137
155
|
module StructParam
|
138
156
|
extend FFI::Library
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Meissner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-10 00:00:00 +10:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,16 +22,6 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 0.8.7
|
24
24
|
version:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: bones
|
27
|
-
type: :development
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 3.2.1
|
34
|
-
version:
|
35
25
|
description: |-
|
36
26
|
Ruby-FFI is a ruby extension for programmatically loading dynamic
|
37
27
|
libraries, binding functions within them, and calling those functions
|
@@ -47,7 +37,6 @@ extensions:
|
|
47
37
|
extra_rdoc_files:
|
48
38
|
- History.txt
|
49
39
|
- README.rdoc
|
50
|
-
- lib/ffi_c.so
|
51
40
|
files:
|
52
41
|
- History.txt
|
53
42
|
- LICENSE
|
@@ -372,7 +361,6 @@ files:
|
|
372
361
|
- lib/ffi/types.rb
|
373
362
|
- lib/ffi/union.rb
|
374
363
|
- lib/ffi/variadic.rb
|
375
|
-
- lib/ffi_c.so
|
376
364
|
- spec/ffi/bool_spec.rb
|
377
365
|
- spec/ffi/buffer_spec.rb
|
378
366
|
- spec/ffi/callback_spec.rb
|
data/lib/ffi_c.so
DELETED
Binary file
|