nice-ffi 0.2 → 0.3

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.
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