From: Charles Oliver Nutter Date: 2010-01-26T16:58:06+09:00 Subject: Re: ruby bounties--list of bounties On Mon, Jan 25, 2010 at 7:53 PM, Aaron Patterson wrote: > References please. > > Last I checked, it was just as easy to segv from an FFI library as a C > library.  Plus with FFI you don't get any benefits of compile time > checks.  You can't, for example, check for #define constants. Code you don't write can't cause a segfault. FFI allows you to write less C, and from my experience the more C code you write the more likely you are to blow something up. FFI certainly doesn't protect you from other possible segfaults, like calling into libraries incorrectly or defining bad struct sizes or mismanaging memory, but it is at least less C code to write and maintain. I will grant there's a lot of up-front cost required (currently) that may make it no easier than maintaining all that C code. > With FFI you must: > > 1. Duplicate header files (see below for more problems) > 2. Understand struct layouts and the sizeof() for each member > 3. Do runtime checking of library features > 4. Worry about weak ref maps when using void pointers (see the id2ref >   problem in nokogiri) > 5. Pay a runtime conversion price from ruby data types to FFI types > 6. Educate users on LD_LIBRARY_PATH > 7. Worry about 32bit and 64bit issues (like Tony mentioned) Yeah, I will admit there's more hassle using FFI than there should be. I don't know how to address that, but projects like ffi-inliner seem to be a step in the right direction. FFI-inliner basically allows you to have some embedded C code in your FFI-consuming library that it then compiles and links in via FFI. That allows you to get the compile-time tooling you want for wrangling nontrivial structs while still supporting any implementation that supports FFI. You lose the ability to run on platforms without a compiler available (though it does some wrangling with tcc, I believe), but it may be a good happy medium. What do you think? I don't want to give the impression that you shouldn't use C tooling to call a C library, or even that nobody should ever write C code. I just believe that everyone writing C code that depends on MRI's C API is a dead end. > Unfortunately, none of the problems I've just listed off are > theoretical.  I have personally run in to every one of them and can > provide you with real world examples.  FFI is awesome for certain, > confined, small, stable use cases.  I use FFI, and I enjoy it.  But > saying that it's "the only logical choice" seems wrong. I'll restate it: using mechanisms for binding C libraries that don't depend on MRI's C API is the only logical choice. FFI certainly isn't perfect, but it's the best option for doing that right now. > I am curious what your experience has been, and why you haven't run in to the > same problems?  How do other people overcome these issues? We certainly have run into some of those issues, most notably when trying to support "stat" calls from JRuby across all platforms. Our only option has been to rewire the struct and call for each platform we intend to run on. It sucks, I agree. But we support stat on all those platforms out of a single JRuby distribution without a recompile being necessary. That's pretty cool. - Charlie