nice-ffi 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog.txt CHANGED
@@ -1,3 +1,53 @@
1
+ ------------------------------------------------------------
2
+ Author: John Croisant <jacius@gmail.com>
3
+ Date: Sun Jan 17 21:04:08 2010 -0600
4
+
5
+ Nice-FFI 0.3 released.
6
+
7
+ ------------------------------------------------------------
8
+ Author: John Croisant <jacius@gmail.com>
9
+ Date: Sun Jan 17 20:53:30 2010 -0600
10
+
11
+ Updated version and copyright dates.
12
+
13
+ M README.rdoc
14
+ M lib/nice-ffi/pathset.rb
15
+ M lib/nice-ffi/struct.rb
16
+ M nice-ffi.gemspec
17
+
18
+ ------------------------------------------------------------
19
+ Author: John Croisant <jacius@gmail.com>
20
+ Date: Sun Jan 17 20:53:05 2010 -0600
21
+
22
+ Fixed AutoPointer errors in opaquestruct_spec.rb.
23
+
24
+ M spec/opaquestruct_spec.rb
25
+
26
+ ------------------------------------------------------------
27
+ Author: John Croisant <jacius@gmail.com>
28
+ Date: Sun Jan 17 20:14:06 2010 -0600
29
+
30
+ Struct creates Buffer instead of MemoryPointer.
31
+
32
+ M lib/nice-ffi/struct.rb
33
+
34
+ ------------------------------------------------------------
35
+ Author: John Croisant <jacius@gmail.com>
36
+ Date: Mon Jan 11 15:35:01 2010 -0600
37
+
38
+ Improved filename globs for Pathset::DEFAULT.
39
+
40
+ M docs/usage.rdoc
41
+ M lib/nice-ffi/pathset.rb
42
+
43
+ ------------------------------------------------------------
44
+ Author: John Croisant <jacius@gmail.com>
45
+ Date: Thu Dec 10 13:50:24 2009 -0600
46
+
47
+ Updated Struct to play well with Buffers.
48
+
49
+ M lib/nice-ffi/struct.rb
50
+
1
51
  ------------------------------------------------------------
2
52
  Author: John Croisant <jacius@gmail.com>
3
53
  Date: Sat Oct 24 15:58:31 2009 -0500
data/README.rdoc CHANGED
@@ -1,12 +1,12 @@
1
1
 
2
2
  = Nice-FFI
3
3
 
4
- Version:: 0.2
5
- Date:: 2009-10-24
4
+ Version:: 0.3
5
+ Date:: 2010-01-17
6
6
 
7
7
  Homepage:: http://github.com/jacius/nice-ffi/
8
8
  Author:: John Croisant <jacius@gmail.com>
9
- Copyright:: 2009 John Croisant
9
+ Copyright:: 2009-2010 John Croisant
10
10
 
11
11
 
12
12
  == Description
@@ -54,7 +54,7 @@ match the new API, then you should wait until version 1.0.
54
54
 
55
55
  == Requirements
56
56
 
57
- * Ruby-FFI >= 0.4.0 (or compatible FFI implementation)
57
+ * Ruby-FFI >= 0.5.0 (or compatible FFI implementation)
58
58
 
59
59
 
60
60
  == Usage
@@ -66,7 +66,7 @@ See docs/usage.rdoc for usage information.
66
66
 
67
67
  Nice-FFI is licensed under the following terms (the "MIT License"):
68
68
 
69
- Copyright (c) 2009 John Croisant
69
+ Copyright (c) 2009-2010 John Croisant
70
70
 
71
71
  Permission is hereby granted, free of charge, to any person obtaining
72
72
  a copy of this software and associated documentation files (the
data/docs/usage.rdoc CHANGED
@@ -62,12 +62,15 @@ library in likely directories. Specifically, it looks for:
62
62
  }
63
63
 
64
64
  files = {
65
- /linux|bsd/ => [ "lib[NAME].so" ],
65
+ /linux|bsd/ => [ "lib[NAME].so*",
66
+ "lib[NAME]-*.so*" ],
66
67
 
67
68
  /darwin/ => [ "lib[NAME].dylib",
69
+ "lib[NAME]-*.dylib",
68
70
  "[NAME].framework/[NAME]" ],
69
71
 
70
- /windows/ => [ "[NAME].dll" ]
72
+ /windows/ => [ "[NAME].dll",
73
+ "[NAME]-*.dll"]
71
74
  }
72
75
 
73
76
  NiceFFI::PathSet::DEFAULT = NiceFFI::PathSet.new( paths, files )
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # Nice-FFI - Convenience layer atop Ruby-FFI
6
6
  #
7
- # Copyright (c) 2009 John Croisant
7
+ # Copyright (c) 2009-2010 John Croisant
8
8
  #
9
9
  # Permission is hereby granted, free of charge, to any person obtaining
10
10
  # a copy of this software and associated documentation files (the
@@ -579,12 +579,15 @@ paths = {
579
579
  }
580
580
 
581
581
  files = {
582
- /linux|bsd/ => [ "lib[NAME].so" ],
582
+ /linux|bsd/ => [ "lib[NAME].so*",
583
+ "lib[NAME]-*.so*" ],
583
584
 
584
585
  /darwin/ => [ "lib[NAME].dylib",
586
+ "lib[NAME]-*.dylib",
585
587
  "[NAME].framework/[NAME]" ],
586
588
 
587
- /windows/ => [ "[NAME].dll" ]
589
+ /windows/ => [ "[NAME].dll",
590
+ "[NAME]-*.dll"]
588
591
  }
589
592
 
590
593
  # The default paths to look for libraries. See PathSet
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # Nice-FFI - Convenience layer atop Ruby-FFI
6
6
  #
7
- # Copyright (c) 2009 John Croisant
7
+ # Copyright (c) 2009-2010 John Croisant
8
8
  #
9
9
  # Permission is hereby granted, free of charge, to any person obtaining
10
10
  # a copy of this software and associated documentation files (the
@@ -265,7 +265,7 @@ class NiceFFI::Struct < FFI::Struct
265
265
  else
266
266
  self.class_eval do
267
267
  define_method( member ) do
268
- return nil if self.pointer.null?
268
+ return nil if self.pointer.null? rescue NoMethodError
269
269
  return self[member]
270
270
  end
271
271
  end
@@ -338,23 +338,23 @@ class NiceFFI::Struct < FFI::Struct
338
338
  case val
339
339
 
340
340
  when Hash
341
- super() # Create empty struct
341
+ super(FFI::Buffer.new(size))
342
342
  init_from_hash( val ) # Read the values from a Hash.
343
343
 
344
344
  # Note: plain "Array" would mean FFI::Struct::Array in this scope.
345
345
  when ::Array
346
- super() # Create empty struct
346
+ super(FFI::Buffer.new(size))
347
347
  init_from_array( val ) # Read the values from an Array.
348
348
 
349
349
  when String
350
- super() # Create empty struct
350
+ super(FFI::Buffer.new(size))
351
351
  init_from_bytes( val ) # Read the values from a bytestring.
352
352
 
353
353
  when self.class
354
- super() # Create empty struct
354
+ super(FFI::Buffer.new(size))
355
355
  init_from_bytes( val.to_bytes ) # Read the values from another instance.
356
356
 
357
- when FFI::Pointer
357
+ when FFI::Pointer, FFI::Buffer
358
358
  val = _make_autopointer( val, options[:autorelease] )
359
359
 
360
360
  # Normal FFI::Struct behavior to wrap the pointer.
@@ -428,8 +428,11 @@ class NiceFFI::Struct < FFI::Struct
428
428
 
429
429
 
430
430
  def to_s
431
- if self.pointer.null?
432
- return "#<NULL %s:%#.x>"%[self.class.name, self.object_id]
431
+ begin
432
+ if self.pointer.null?
433
+ return "#<NULL %s:%#.x>"%[self.class.name, self.object_id]
434
+ end
435
+ rescue NoMethodError
433
436
  end
434
437
 
435
438
  mems = members.collect{ |m|
@@ -0,0 +1,88 @@
1
+
2
+ = Nice-FFI
3
+
4
+ Version:: 0.2
5
+ Date:: 2009-10-24
6
+
7
+ Homepage:: http://github.com/jacius/nice-ffi/
8
+ Author:: John Croisant <jacius@gmail.com>
9
+ Copyright:: 2009 John Croisant
10
+
11
+
12
+ == Description
13
+
14
+ Nice-FFI is a layer on top of Ruby-FFI [1] (and compatible FFI
15
+ systems) with features to ease development of FFI-based libraries.
16
+
17
+ Nice-FFI currently features:
18
+
19
+ * NiceFFI::Library: a stand-in for FFI::Library that provides methods
20
+ for easily finding and loading libraries on any platform, plus
21
+ automatic wrapping of functions that return struct pointers.
22
+
23
+ * NiceFFI::PathSet: a class with customizable rules for finding
24
+ library files on multiple operating system. PathSet is used by
25
+ NiceFFI::Library.load_library.
26
+
27
+ * NiceFFI::Struct: a stand-in for FFI::Struct that provides automatic
28
+ accessors for struct members, optional automatic memory management,
29
+ more instance initialization options, pretty to_s and inspect
30
+ methods, and other niceties.
31
+
32
+ * NiceFFI::OpaqueStruct: a base class for structs with no user-exposed
33
+ members. Useful when the struct definition is hidden by the
34
+ underlying C library.
35
+
36
+ Nice-FFI was originally developed as part of Ruby-SDL-FFI [2].
37
+
38
+ 1. Ruby-FFI: http://github.com/ffi/ffi
39
+ 2. Ruby-SDL-FFI: http://github.com/jacius/ruby-sdl-ffi/
40
+
41
+
42
+ == Caveats
43
+
44
+ Nice-FFI is still in EARLY DEVELOPMENT STAGES. That means:
45
+
46
+ * It may not work correctly (or at all).
47
+ * It may not be complete.
48
+ * It may change drastically with no advanced notice.
49
+
50
+ As such, this library is currently FOR THE ADVENTUROUS ONLY.
51
+ If you are not willing to continuously update your code to
52
+ match the new API, then you should wait until version 1.0.
53
+
54
+
55
+ == Requirements
56
+
57
+ * Ruby-FFI >= 0.4.0 (or compatible FFI implementation)
58
+
59
+
60
+ == Usage
61
+
62
+ See docs/usage.rdoc for usage information.
63
+
64
+
65
+ == License
66
+
67
+ Nice-FFI is licensed under the following terms (the "MIT License"):
68
+
69
+ Copyright (c) 2009 John Croisant
70
+
71
+ Permission is hereby granted, free of charge, to any person obtaining
72
+ a copy of this software and associated documentation files (the
73
+ "Software"), to deal in the Software without restriction, including
74
+ without limitation the rights to use, copy, modify, merge, publish,
75
+ distribute, sublicense, and/or sell copies of the Software, and to
76
+ permit persons to whom the Software is furnished to do so, subject to
77
+ the following conditions:
78
+
79
+ The above copyright notice and this permission notice shall be
80
+ included in all copies or substantial portions of the Software.
81
+
82
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
83
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
84
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
85
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
86
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
87
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
88
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,16 @@
1
+
2
+ = TODO
3
+
4
+ * Struct
5
+ * Write accessor for nested structs (not struct pointers).
6
+ See comment in NiceFFI::Struct._make_writer for details.
7
+
8
+ * Specs
9
+ * Library (use a mock for ffi_lib.)
10
+ * PathSet#find (use a mock for File.exist?.)
11
+ * Struct
12
+ * TypedPointer
13
+
14
+ * Better documentation comments
15
+ * Library#attach_function
16
+ * Library#load_library
@@ -0,0 +1,361 @@
1
+ = Using Nice-FFI
2
+
3
+ This is a guide on how to use Nice-FFI's features. It assumes that you
4
+ are already somewhat familiar with Ruby-FFI.
5
+
6
+
7
+ == NiceFFI::Library
8
+
9
+ NiceFFI::Library is a drop-in replacement for FFI::Library. It provides
10
+ improved library finding abilities and support for TypedPointer return
11
+ types for attached functions.
12
+
13
+
14
+ In fact, NiceFFI::Library *is* FFI::Library, but with a few extras.
15
+ That means that you can do all the regular FFI::Library stuff as well
16
+ as the stuff described here.
17
+
18
+
19
+ === load_library
20
+
21
+ NiceFFI::Library.load_library is a more convenient replacement for
22
+ FFI::Library.ffi_lib. It uses NiceFFI::PathSet to search for the
23
+ library in the most likely places, depending on the user's operating
24
+ system. For example, on Linux it would look for "lib[NAME].so" in
25
+ "/usr/lib/" (among others), while on Windows it would look for
26
+ "[NAME].dll" in "C:\windows\system32\".
27
+
28
+ Using load_library is easy. Just use "extend NiceFFI::Library" instead
29
+ of "extend FFI::Library", and use "load_library" instead of "ffi_lib":
30
+
31
+
32
+ require 'nice-ffi'
33
+
34
+ module MyLibraryModule
35
+ extend NiceFFI::Library
36
+
37
+ load_library("SDL") # look for libSDL.so, SDL.dll, etc.
38
+
39
+ # structs, functions, etc. as usual.
40
+
41
+ end
42
+
43
+
44
+ ==== Advanced load_library
45
+
46
+ As mentioned, load_library uses NiceFFI::PathSet to search for the
47
+ library in likely directories. Specifically, it looks for:
48
+
49
+
50
+ paths = {
51
+ /linux|bsd/ => [ "/usr/local/lib/",
52
+ "/usr/lib/" ],
53
+
54
+ /darwin/ => [ "/usr/local/lib/",
55
+ "/sw/lib/",
56
+ "/opt/local/lib/",
57
+ "~/Library/Frameworks/",
58
+ "/Library/Frameworks/" ],
59
+
60
+ /windows/ => [ "C:\\windows\\system32\\",
61
+ "C:\\windows\\system\\" ]
62
+ }
63
+
64
+ files = {
65
+ /linux|bsd/ => [ "lib[NAME].so" ],
66
+
67
+ /darwin/ => [ "lib[NAME].dylib",
68
+ "[NAME].framework/[NAME]" ],
69
+
70
+ /windows/ => [ "[NAME].dll" ]
71
+ }
72
+
73
+ NiceFFI::PathSet::DEFAULT = NiceFFI::PathSet.new( paths, files )
74
+
75
+
76
+ The paths hash tells PathSet where to look for libraries, and the
77
+ files hash tells it the format of the library filename itself. The
78
+ string "[NAME]" is replaced with whatever string you pass to
79
+ load_library.
80
+
81
+ Each key in the hash should be a Regexp that matches an OS name from
82
+ FFI::Platform::OS. As of this writing (October 2009), the list of
83
+ recognized OS names is:
84
+
85
+ * "darwin" (MacOS X)
86
+ * "freebsd"
87
+ * "linux"
88
+ * "openbsd"
89
+ * "solaris"
90
+ * "windows"
91
+
92
+ So, if the user is running Linux and you try to load "SDL", it will
93
+ first look for "/usr/local/lib/libSDL.so". If it can't find that, it
94
+ will then look for "/usr/lib/libSDL.so". It would also use those same
95
+ paths for FreeBSD or OpenBSD, because those OS names also match the
96
+ regexp /linux|bsd/.
97
+
98
+ If the library could not be found in any of the given directories with
99
+ the given file name formats, load_library will just try loading "SDL"
100
+ using ffi_lib (which does some platform-appropriate guesses too). If
101
+ that fails too, LoadError is raised.
102
+
103
+ If you want to load from a different path, you can make a custom
104
+ PathSet and pass it to load_library:
105
+
106
+
107
+ libs_dir = File.dirname(__FILE__) + "/libs/"
108
+
109
+ pathset = NiceFFI::PathSet::DEFAULT.prepend( libs_dir )
110
+
111
+ load_library( "SDL", my_pathset )
112
+
113
+
114
+ The above example prepends (adds in front) the new paths so
115
+ that load_library will look for the library in "./libs/" first.
116
+ See PathSet for other useful methods for modifying PathSets.
117
+
118
+
119
+ Another advanced usage tip: If a library has several alternative
120
+ names, you can provide an Array of names:
121
+
122
+
123
+ # It might be called "foo", "foo2", or "Foo".
124
+
125
+ load_library( ["foo", "foo2", "Foo"] )
126
+
127
+
128
+ === attach_function
129
+
130
+ NiceFFI::Library#attach_function behaves similarly to
131
+ FFI::Library#attach_function, except it supports TypedPointer return
132
+ values. For example, suppose you have a C function:
133
+
134
+
135
+ MyStruct *make_my_struct( int x, int y );
136
+
137
+
138
+ This returns a pointer to an instance of MyStruct. With FFI, you'd
139
+ write this to attach it:
140
+
141
+
142
+ attach_function :make_my_struct, [:int, :int], :pointer
143
+
144
+
145
+ And when you called it, it would return an FFI::Pointer, which you
146
+ would then have to manually wrap every time you called the method:
147
+
148
+
149
+ ptr = make_my_struct( 1, 2 )
150
+ mystruct = MyStruct.new( ptr )
151
+
152
+
153
+ With TypedPointer, the wrapping happens automatically. Just attach
154
+ the function with a TypedPointer instead of :pointer:
155
+
156
+
157
+ attach_function :make_my_struct, [:int, :int], NiceFFI::TypedPointer( MyStruct )
158
+
159
+ # If MyStruct is based on NiceFFI::Struct, you can do this instead:
160
+
161
+ attach_function :make_my_struct, [:int, :int], MyStruct.typed_pointer
162
+
163
+
164
+ Then you automatically get a MyStruct instance when you call the function:
165
+
166
+
167
+ mystruct = make_my_struct( 1, 2 )
168
+ mystruct.instance_of?( MyStruct ) # => Heck yeah it sure is!
169
+
170
+
171
+ Voila!
172
+
173
+
174
+ == NiceFFI::Struct
175
+
176
+ NiceFFI::Struct is a replacement for FFI::Struct. It provides several
177
+ features in addition to the normal FFI::Struct behavior:
178
+
179
+ * Ability to construct new instances from Array, Hash, another instance,
180
+ or a pointer as usual.
181
+ * Automatic read and write accessors for struct members.
182
+ * Accessors for struct pointer members with TypedPointer.
183
+ * Ability to dump an instance as an Array (#to_ary) or Hash (#to_hash).
184
+ * Pretty and useful #to_s and #inspect for debugging.
185
+
186
+
187
+ === Constructors
188
+
189
+ NiceFFI::Struct allows you to construct a new struct instance from
190
+ a Hash, Array, or another existing instance of the same struct type.
191
+ It can also accept a pointer, just as with FFI::Struct.
192
+
193
+
194
+ class MyStruct < NiceFFI::Struct
195
+ layout :x, :int,
196
+ :y, :int
197
+ end
198
+
199
+ mystruct = MyStruct.new( {:x => 1, :y => 2} ) # from Hash
200
+ mystruct2 = MyStruct.new( [1,2] ) # from Array
201
+ mystruct3 = MyStruct.new( mystruct ) # from another instance
202
+ mystruct4 = MyStruct.new( ptr ) # from Pointer
203
+
204
+
205
+ === Struct Member Accessors
206
+
207
+ Struct members are defined automatically when you use
208
+ NiceFFI::Struct.layout:
209
+
210
+
211
+ class MyStruct < NiceFFI::Struct
212
+ layout :x, :int,
213
+ :y, :int
214
+ end
215
+
216
+ mystruct = MyStruct.new({:x => 1, :y => 2})
217
+
218
+ mystruct.x # => 1
219
+ mystruct.y # => 2
220
+
221
+ mystruct.x = 3
222
+ mystruct.y = -4
223
+
224
+
225
+ Sometimes a struct will have members that should be read-only,
226
+ or completely hidden. In those cases, you can use
227
+ NiceFFI::Struct.read_only and NiceFFI::Struct.hidden.
228
+
229
+
230
+ class MySneakyStruct < NiceFFI::Struct
231
+ layout :readme, :int,
232
+ :readme2, :int,
233
+ :hideme, :pointer,
234
+ :hideme2, :pointer,
235
+ :normal, :uint32
236
+
237
+ read_only :readme, :readme2
238
+ hidden :hideme, :hideme2
239
+ end
240
+
241
+ sneaky = MySneakyStruct.new( ... )
242
+
243
+
244
+ read_only prevents a write accessor from being created (or removes
245
+ it if there is already one). hidden does the same, but for both
246
+ read and write accessors. hidden also prevents the member from
247
+ being shown in #to_s and #inspect.
248
+
249
+ read_only and hidden can go before or after layout (or both),
250
+ and you can safely call them multiple times if you need to.
251
+
252
+
253
+ === TypedPointer Struct Member Accessors
254
+
255
+ Some struct members are :pointers that point to other structs.
256
+ With FFI::Struct, you'd have to manually wrap and unwrap the
257
+ struct pointer, but if you specify a TypedPointer instead of
258
+ :pointer, NiceFFI::Struct will wrap and unwrap it automatically:
259
+
260
+
261
+ class StructWithPtr < NiceFFI::Struct
262
+ layout :x, :int,
263
+ :y, :int,
264
+ :my, NiceFFI::TypedPointer( MyStruct )
265
+ end
266
+
267
+ struct = StructWithPtr.new( :x => -1,
268
+ :y => -2,
269
+ :my => MyStruct.new([1,2]) )
270
+
271
+ # Seamlessly wraps the pointer in a struct
272
+ struct.my.kind_of? MyStruct # true
273
+
274
+ # Seamlessly unwraps the struct and stores the pointer
275
+ struct.my = MyStruct.new([-4,-3])
276
+
277
+
278
+ === Automatic Memory Managment
279
+
280
+ Ruby-FFI already provides automatic memory management when you create
281
+ a FFI::MemoryPointer or FFI::Buffer instance. When those instances are
282
+ garbage collected, their memory is automatically released so it can be
283
+ used elsewhere.
284
+
285
+ That feature is used by NiceFFI::Struct when you create a new instance
286
+ by passing a Hash, Array, String, or another instance. In those cases,
287
+ new memory is allocated for the struct instance, and automatically
288
+ released when the struct instance is galbage collected.
289
+
290
+ NiceFFI::Struct also provides an optional automatic memory management
291
+ system for normal pointers. To use this system, define a "release"
292
+ class method in your class. Then if you create a new struct instance
293
+ with an FFI::Pointer, the release class method will automatically be
294
+ called when the memory for a struct instance needs to be freed.
295
+
296
+ (This also applies to attached functions with TypedPointer return
297
+ values. The pointers returned from those functions are wrapped in the
298
+ struct class, so if you have defined the release class method, they
299
+ will be automatically memory managed.)
300
+
301
+ The release class method must accept an FFI::Pointer and call an
302
+ appropriate function to free the struct's memory. Here's an example
303
+ from Ruby-SDL-FFI:
304
+
305
+
306
+ class Surface < NiceFFI::Struct
307
+
308
+ def self.release( pointer )
309
+ SDL.FreeSurface( pointer )
310
+ end
311
+
312
+ # ...
313
+
314
+ end
315
+
316
+
317
+ Note: the release class method should not have any side effects
318
+ besides freeing the struct's memory. Don't be clever!
319
+
320
+ The memory management system keeps a reference count for each pointer
321
+ address, so the release class method will only be called when all
322
+ struct instances that are using that memory have been garbage
323
+ collected. That means it's safe to have many instances sharing the
324
+ same memory.
325
+
326
+ If you want to create an instance that doesn't use the memory
327
+ management system, you can disable the :autorelease option when
328
+ creating the instance, like so:
329
+
330
+
331
+ struct = MyStructClass.new( a_pointer, :autorelease => false )
332
+
333
+
334
+ == NiceFFI::OpaqueStruct
335
+
336
+ Some C libraries have structs with no publicly-visible layout.
337
+ Instead, the internal details are hidden, and only modified by calling
338
+ functions in the library.
339
+
340
+ For example, the SDL_mixer library has this definition in its header
341
+ file:
342
+
343
+
344
+ typedef struct _Mix_Music Mix_Music;
345
+
346
+
347
+ "_Mix_Music" is a struct that is defined within SDL_mixer, but its
348
+ internals are different depending on what features SDL_mixer was
349
+ compiled with. The struct members are not revealed in the header file,
350
+ so they can't be accessed like a normal struct.
351
+
352
+ NiceFFI provides a class for handling special cases like this,
353
+ NiceFFI::OpaqueStruct. OpaqueStruct has no layout and no members, and
354
+ cannot be created by passing in Hashes, Arrays, etc. It simply holds a
355
+ pointer to the struct memory. As with NiceStruct (and FFI::Struct),
356
+ instances of OpaqueStruct-based classes can be passed directly to
357
+ functions expecting a pointer of the appropriate struct type.
358
+
359
+ OpaqueStruct features the same optional memory management system as
360
+ NiceStruct. Read the "Automatic Memory Management" section above for
361
+ information about how to use this feature.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nice-ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.2"
4
+ version: "0.3"
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Croisant
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-24 00:00:00 -05:00
12
+ date: 2010-01-17 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -34,6 +34,9 @@ extensions: []
34
34
  extra_rdoc_files: []
35
35
 
36
36
  files:
37
+ - pkg/nice-ffi-0.2/docs/usage.rdoc
38
+ - pkg/nice-ffi-0.2/TODO.rdoc
39
+ - pkg/nice-ffi-0.2/README.rdoc
37
40
  - docs/usage.rdoc
38
41
  - TODO.rdoc
39
42
  - README.rdoc