On Tue, Jan 26, 2010 at 03:12:17AM +0900, Charles Oliver N. wrote:
On Mon, Jan 25, 2010 at 6:25 PM, Mike D. [email protected] wrote:
Charlie, you’re making a great case against using FFI.
FFI is much better than writing any C code at all, due to the
security, stability, and portability problems of writing your own C
bindings.
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.
With FFI you must:
- Duplicate header files (see below for more problems)
- Understand struct layouts and the sizeof() for each member
- Do runtime checking of library features
- Worry about weak ref maps when using void pointers (see the id2ref
problem in nokogiri)
- Pay a runtime conversion price from ruby data types to FFI types
- Educate users on LD_LIBRARY_PATH
- Worry about 32bit and 64bit issues (like Tony mentioned)
The duplication of header files becomes an even larger problem if the
library you’re wrapping changes it’s struct layout. Where a simple
recompile would have solved the problem, now (without warning) you’re
getting
surprising values in your FFI program. Plus typical debugging tools
like gdb get you nowhere.
Example:
Library “foo” ships with a struct like this:
struct awesome {
float hello;
char * world;
};
Then later changes to:
struct awesome {
char * world;
float hello;
};
You wrapped the first one, upgrade the library, then boom. It doesn’t
work.
With a compiled program, you wouldn’t care.
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 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?