Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 376 lines (293 sloc) 12.527 kb
9593352 Nick Quaranto add c extension fixture
qrush authored
1 ---
2 layout: default
3 title: C Extensions
4 previous: /run-your-own-gem-server
5 next: /resources
6 ---
7
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
8 This guide explains how to package a C extension as a rubygem.
9
10 To get started, we'll add a C method to the `hola` gem from the
11 [make your own gem](/make-your-own-gem) guide. Then there's some general
12 [advice](#advice) and some [references](#references) for further reading.
13
14 <a id="tutorial"> </a>
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
15 Tutorial: Add a C extension to `hola`
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
16 ========================================
17
18 At the end of the [make your own gem](/make-your-own-gem) guide, `hola` looked
19 like this:
20
21 % tree
22 .
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
23 ├── bin
24 │ └── hola
25 ├── hola.gemspec
26 ├── lib
27 │ ├── hola
28 │ │ └── translator.rb
29 │ └── hola.rb
30 ├── Rakefile
31 └── test
32 └── test_hola.rb
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
33
34 Now we'll add in a simple C extension.
35
36 <a id="tutorial-ext"> </a>
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
37 Create an `ext` directory
38 -------------------------
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
39
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
40 Just as we put the ruby source files in the `lib/hola` directory, we put the C
41 extension source files in `ext/hola`. This directory contains two files:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
42
43 % tree ext
44 ext
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
45 └── hola
46 ├── extconf.rb
47 └── hola.c
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
48
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
49 Create `extconf.rb`
50 -------------------
4f31dda Mike Gunderloy Standardize capitalization to 'RubyGems'
ffmike authored
51 `extconf.rb` tells RubyGems how to build the extension. For `hola`, it reads:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
52
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
53 % cat ext/hola/extconf.rb
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
54 require 'mkmf'
55
56 create_makefile('hola/hola')
57
ac02999 Gabriel Horner more c extension guide tweaks, per @jdleesmiller + @luislavena, #10
cldwalker authored
58 `mkmf`, a ruby standard library, automates the process of creating
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
59 a [Makefile](http://en.wikipedia.org/wiki/Makefile) which, in turn, automates
4f31dda Mike Gunderloy Standardize capitalization to 'RubyGems'
ffmike authored
60 the process of building the extension. When RubyGems installs a gem, it
ac02999 Gabriel Horner more c extension guide tweaks, per @jdleesmiller + @luislavena, #10
cldwalker authored
61 runs the gem's `extconf.rb` and then runs `make` on the resulting
62 `Makefile`. The output from make is a [dynamically linked
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
63 library](http://en.wikipedia.org/wiki/Shared_object). The naming conventions for these
64 libraries is platform dependent. You can use this bit of code to find the
65 filename extension used on your platform for dynamically linked libraries:
ac02999 Gabriel Horner more c extension guide tweaks, per @jdleesmiller + @luislavena, #10
cldwalker authored
66
67 % irb -rrbconfig
68 >> RbConfig::CONFIG['DLEXT']"
69 # extensions are .bundle on my OS
70 => bundle
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
71
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
72 Create the C extension
73 ----------------------
74 In general, a good convention for the c file name is
75 `ext/<gem_name>/<gem_name>.c`. While it is somewhat annoying to repeat the gem
76 name in so many places, it helps to avoid [naming conflicts](#naming), which are
77 even more annoying.
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
78
79 The C source code for the extension is in `hola.c`, which reads:
80
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
81 % cat ext/hola/hola.c
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
82 #include <ruby.h>
83
84 /* our new native method; it just returns
85 * the string "bonjour!" */
86 static VALUE hola_bonjour(VALUE self) {
87 return rb_str_new2("bonjour!");
88 }
89
90 /* ruby calls this to load the extension */
91 void Init_hola(void) {
92 /* assume we haven't yet defined Hola */
93 VALUE klass = rb_define_class("Hola",
94 rb_cObject);
95
96 /* the hola_bonjour function can be called
97 * from ruby as "Hola.bonjour" */
98 rb_define_singleton_method(klass,
99 "bonjour", hola_bonjour, 0);
100 }
101
102 `ruby.h` provides declarations for ruby's C API, which is where the `rb_...`
103 methods come from. The `Makefile` generated by `mkmf` ensures that the compiler
104 knows where this header file is. Some [references](#references) for ruby's C API
105 are given at the end of this guide.
106
107 Again, the name of the file is important, because it matches the second `hola`
108 in the `hola/hola` that we passed to `create_makefile` in `extconf.rb`.
109 Similarly, the name of the `Init_hola` function is important, because ruby looks
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
110 for a function with this name when it loads `hola/hola.so`. There is a [summary of these
111 naming rules](#naming) at the end of the guide.
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
112
113 <a id="tutorial-gemspec"> </a>
114 Modify the `gemspec`
115 --------------------
116
4f31dda Mike Gunderloy Standardize capitalization to 'RubyGems'
ffmike authored
117 For RubyGems to know that a gem contains a C extension, we have to tell it about
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
118 `extconf.rb`, and we have to include the C source files in the `files` list. As
119 you should expect, this happens in the gemspec:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
120
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
121 % cat hola.gemspec
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
122 Gem::Specification.new do |s|
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
123 # ... (other stuff) ...
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
124
125 s.files = Dir.glob('lib/**/*.rb') +
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
126 Dir.glob('ext/**/*.{c,h,rb}')
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
127 s.extensions = ['ext/hola/extconf.rb']
128 s.executables = ['hola']
129
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
130 # ... (other stuff) ...
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
131 end
132
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
133 This gemspec computes the `files` list dynamically; when you run `gem build`,
4f31dda Mike Gunderloy Standardize capitalization to 'RubyGems'
ffmike authored
134 RubyGems will include all matching files in the gem. RubyGems automatically
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
135 adds the `extensions` and `executables` to the gem, so you don't have to list
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
136 them under `files`.
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
137
138 <a id="tutorial-load"> </a>
139 Load the extension
140 ------------------
141
142 The final step is to require the shared object so that ruby will load the
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
143 extension with the rest of the gem. To do this, simply require `hola/hola` in
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
144 `lib/hola.rb`:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
145
146 % cat lib/hola.rb
147 require 'hola/hola'
148
149 ... (rest of file unchanged) ...
150
4f31dda Mike Gunderloy Standardize capitalization to 'RubyGems'
ffmike authored
151 This works because RubyGems copies the shared object from `ext` to `lib` when
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
152 the gem is installed. It seems a bit like magic, but now you can build and
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
153 install the gem to see what's going on:
154
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
155 % gem build hola.gemspec
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
156 Successfully built RubyGem
157 Name: hola
158 Version: 0.0.1
159 File: hola-0.0.1.gem
160
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
161 The `gem build` command creates a `.gem` file from the `.gemspec`. The Gemfile includes
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
162 all of the source files, but it doesn't compile the extension; that happens when
163 the gem is installed:
164
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
165 % gem install hola-0.0.1.gem
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
166 Building native extensions. This could take a while...
167 Successfully installed hola-0.0.1
168 1 gem installed
169
170 Where exactly the gem is installed to depends on how ruby is set up. On Linux
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
171 with [rvm](http://beginrescueend.com/), the gem is installed into a directory
172 structure resembling this:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
173
174 % tree ~/.rvm/gems/ruby-1.8.7-p352/gems/hola-0.0.1/
175 /home/john/.rvm/gems/ruby-1.8.7-p352/gems/hola-0.0.1/
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
176 ├── bin
177 │ └── hola
178 ├── ext
179 │ └── hola
180 │ ├── extconf.rb
181 │ ├── hola.c
182 │ ├── hola.o
183 │ ├── hola.so
184 │ └── Makefile
185 ├── lib
186 │ ├── hola
187 │ │ ├── hola.so # <----
188 │ │ └── translator.rb
189 │ └── hola.rb
190 └── test
191 └── test_hola.rb
192
193 You can see that the `ext/hola` directory contains the `extconf.rb` and `hola.c`
194 files. You can also see that the install has generated a Makefile, a `hola.o`
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
195 object file generated by the compiler, and the finished product, `hola.so`. And
196 as mentioned before, notice that `hola.so` has been copied to `lib/hola`.
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
197
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
198 When you require the gem, RubyGems adds `hola`'s `lib` directory to `$LOAD_PATH`,
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
199 which is where `require` looks for files:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
200
201 % irb -rubygems
202 ruby-1.8.7-p352 :001 > require 'hola'
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
203 => true
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
204 ruby-1.8.7-p352 :002 > puts $LOAD_PATH
205 /home/john/.rvm/gems/ruby-1.8.7-p352/gems/hola-0.0.1/lib
206 ... (lots of standard paths) ...
207 .
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
208 => nil
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
209
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
210 Finally, you can call the C extension's `bonjour` method from ruby code:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
211
212 ruby-1.8.7-p352 :003 > Hola.bonjour
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
213 => "bonjour!"
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
214
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
215 The string `"bonjour!"` came from our C extension. Hooray!
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
216
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
217 Of course, you should also add a test to the test suite:
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
218
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
219 % cat test/test_hola.rb
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
220 require 'test/unit'
221 require 'hola'
222
223 class HolaTest < Test::Unit::TestCase
224
225 ... (other tests) ...
226
227 def test_bonjour
228 assert_equal "bonjour!", Hola.bonjour
229 end
230 end
231
232 <a id="tutorial-rakefile"> </a>
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
233 Add `Rake` tasks
234 ----------------
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
235
236 Building and installing the gem every time you make a change quickly gets
237 tedious. To speed things up, it helps to add some extra tasks to your Rakefile
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
238 that automate the build process. The following should work on any unix. For
239 cross-platform `Rake` tasks see
240 [rake-compiler](https://github.com/luislavena/rake-compiler).
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
241
242 require 'rake/testtask'
243 require 'rake/clean'
244
245 NAME = 'hola'
246
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
247 # rule to build the extension: this says
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
248 # that the extension should be rebuilt
249 # after any change to the files in ext
250 file "lib/#{NAME}/#{NAME}.so" =>
251 Dir.glob("ext/#{NAME}/*{.rb,.c}") do
252 Dir.chdir("ext/#{NAME}") do
253 # this does essentially the same thing
4f31dda Mike Gunderloy Standardize capitalization to 'RubyGems'
ffmike authored
254 # as what RubyGems does
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
255 ruby "extconf.rb"
256 sh "make"
257 end
258 cp "ext/#{NAME}/#{NAME}.so", "lib/#{NAME}"
259 end
260
261 # make the :test task depend on the shared
262 # object, so it will be built automatically
263 # before running the tests
264 task :test => "lib/#{NAME}/#{NAME}.so"
265
266 # use 'rake clean' and 'rake clobber' to
267 # easily delete generated files
268 CLEAN.include('ext/**/*{.o,.log,.so}')
269 CLEAN.include('ext/**/Makefile')
270 CLOBBER.include('lib/**/*.so')
271
272 # the same as before
273 Rake::TestTask.new do |t|
274 t.libs << 'test'
275 end
276
277 desc "Run tests"
278 task :default => :test
279
e205af3 Mike Gunderloy Editing pass over C Extensions page
ffmike authored
280 Now typing `rake` will build (or rebuild) the extension before running the tests, as necessary:
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
281
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
282 % rake
283 (in /home/john/rubygems_hola)
284 /home/john/.rvm/rubies/ruby-1.8.7-p352/bin/ruby extconf.rb
285 creating Makefile
286 make
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
287 # gcc output ...
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
288 cp ext/hola/hola.so lib/hola
289 Loaded suite /home/john/.rvm/gems/ruby-1.8.7-p352/gems/rake-0.8.7/lib/rake/rake_test_loader
290 Started
291 ....
292 Finished in 0.00182 seconds.
293
294 4 tests, 4 assertions, 0 failures, 0 errors
295
296 If the C source and `extconf.rb` build script have not changed, then running
297 `rake` a second time runs only the test suite.
298
299 The code for this tutorial is [available on
300 github](https://github.com/jdleesmiller/hola).
301
b709f35 John Lees-Miller added a link to rake-compiler
jdleesmiller authored
302 A good alternative to writing your own Rakefile like the one above is to use the
303 [rake compiler](https://github.com/luislavena/rake-compiler), which does the
304 same stuff -- and much more -- out of the box. It also lets you more easily
305 target multiple platforms and interpreters.
306
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
307 Advice
308 ======
309
310 <a id="naming"> </a>
311 Extension Naming
312 ----------------
313
314 To avoid unintended interactions between gems, it's a good idea for each gem to
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
315 keep all of its files in a single directory. This is the motivation behind the
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
316 naming conventions used in the [tutorial](#tutorial). To summarize, the
317 suggested conventions for a gem with name `$g` are:
318
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
319 1. `ext/$g` is the directory that contains the source files and `extconf.rb`
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
320 1. `ext/$g/$g.c` is the main source file (there may be others)
321 1. `ext/$g/$g.c` contains a function `Init_$g`
322 1. `ext/$g/extconf.rb` calls `create_makefile('$g/$g')`
323 1. the gemspec sets `extensions = ['ext/$g/extconf.rb']` and sets `files` to
324 list any C source or header files in `ext/$g`
325 1. the first require in `lib/$g.rb` is `require '$g/$g'`
326
ac02999 Gabriel Horner more c extension guide tweaks, per @jdleesmiller + @luislavena, #10
cldwalker authored
327 An alternative is to name the extension like `$g_ext` instead of
328 `$g/$g`. The result is that the `$g_ext.so` file is
289b441 Gabriel Horner tweak c-extensions guide for a release, thanks @jdleesmiller, close #10
cldwalker authored
329 installed into the gem's `lib` directory, and it can be required from
ac02999 Gabriel Horner more c extension guide tweaks, per @jdleesmiller + @luislavena, #10
cldwalker authored
330 `lib/$g.rb` as `require '$g_ext'`. This also works, though it is
23d65e2 John Lees-Miller I've filled out the C extension guide. It follows on from the 'make your...
jdleesmiller authored
331 perhaps not as clean as the first convention.
332
333 Wrapping Existing Libraries
334 ---------------------------
335
336 A common reason for writing a C extension is to wrap an existing C or C++
337 library. This can be done manually (see this tutorial --
338 [part
339 1](http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part-1)
340 and [part
341 2](http://tenderlovemaking.com/2010/12/11/writing-ruby-c-extensions-part-2)),
342 but several tools also exist:
343
344 * [SWIG](http://www.swig.org/), the Simplified Wrapper Interface Generator, is
345 mature and probably the most popular
346 * [rb++](http://rbplusplus.rubyforge.org/) is nicer in several ways but is
347 less stable
348
349 Multi-Implementation Extensions
350 -------------------------------
351
352 There are several ruby implementations. C extensions that use the ruby C API can
353 be loaded by the standard ruby interpreter (the MRI -- Matz's Ruby
354 Interpreter) and other C-based interpreters, but they cannot be loaded into
355 [JRuby](http://jruby.org/) (ruby on the Java Virtual machine) or
356 [IronRuby](http://ironruby.net/) (ruby on the Common Language Runtime (.NET)),
357 for example.
358
359 See [ruby-ffi](http://github.com/ffi/ffi) for a way to build extensions that
360 work with other Ruby implementations.
361
362
363 References
364 ==========
365
366 This guide is based largely on this excellent two-part tutorial:
367
368 * [part 1](http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part-1)
369 * [part 2](http://tenderlovemaking.com/2010/12/11/writing-ruby-c-extensions-part-2)
370
371 The main references for ruby's C API are:
372
373 * [a chapter in the Pickaxe book](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html)
374 * [the README.EXT file](https://github.com/ruby/ruby/blob/trunk/README.EXT)
9593352 Nick Quaranto add c extension fixture
qrush authored
375
Something went wrong with that request. Please try again.