Subject: Re: [ruby-ffi] Re: XNI and FFI summary? |
From: Wayne Meissner |
Date: 3/5/13 7:57 PM |
To: ruby-ffi@googlegroups.com |
I think this approach shows a lot of promise. In my opinion, wrapping large libraries is where the C -> Ruby technique really shines. I wonder how maintainable XNI can be for very large APIs like LLVM or OpenGL, and how well it will perform in comparison. (I'm sure there is plenty of low-hanging fruit in XNI's early implementation.)On Tue, Mar 5, 2013 at 2:21 PM, Wayne Meissner <wmei...@gmail.com> wrote:
Yes, the C parsing (whether done by a computer, or a human) is the weakest point of FFI - there are projects that use llvm or swig to produce bindings from the C headers, but with XNI, I wanted to avoid that extra dependency.With XNI, you describe your API in a simple DSL, which is used at both runtime to wire up ruby -> C, and at compile time to generate the C header+stubs. It is a lot easier to produce a clean C api from a simple ruby description, than wrangle a pathological C api into ruby.
There is actually a variant of the stub generator in ffi-compiler - it can take a FFI interface and generate a header with C function signatures and structs.
On Wednesday, 6 March 2013 03:03:02 UTC+10, Jon wrote:> >
> > When you get a free moment, please provide a quick summary of:
> >
> > * XNI's main reason(s) for being
> >
>
> At the moment, its an experiment in native interface design. The aim is a
> stream-lined FFI+ffi-compiler combo, with some hard-coded conventions to
> make it easier to implement common patterns when writing extensions, whilst
> avoiding the "gigantic-ball-of-mud" that is the ruby C api. But, XNI does
> not try to do everything - since you don't get access to Ruby VM internals,
> you wouldn't use it for e.g. implementing a new data structure.
>
> This is Jeremy's hitimes gem converted to use FFI+ffi-compiler:
> https://github.com/wmeissner/hitimes/commit/b226af0498127a9e 25f002b01db9230f68f93f7b
>
> and converted to use XNI:
> https://github.com/wmeissner/hitimes/commit/9252959cebc6678a 969ba672438ba4b11ff98ef5
>
> The XNI one has a bit less ruby boilerplate (XNI has the concept of a
> DataObject, which can have instance methods that automagically pass in
> 'self' to native methods). On the other hand, XNI excises a few FFI
> concepts - there is no Struct that you can wrap around existing native
> memory, nor MemoryPointer for generic native memory allocations.
>
> (as to why I used hitimes - its a fairly nicely written cext, it doesn't do
> anything super-complicated, but would be hard to implement in pure FFI due
> to the data structures and API calls it needs).
>
> * when should one prefer XNI over FFI?
> >
>
> That's a really good question - "when you're unhappy with FFI+ffi-compiler"
> would be the pithy answer. FFI isn't going away, so if people are happy
> with it, then I encourage them to keep using it. At this point, FFI is
> stable and works. On the other hand, if you're writing a gem from scratch,
> and you're going to end up writing a bunch of ruby boilerplate around a raw
> FFI api, and you'll need to use ffi-compiler to compile some native shims,
> then XNI might be worth a look. At least once it is a bit more stable.
>
>
> * will XNI always utilize FFI?
> >
>
> It will always utilize a ffi-like way of interfacing between the ruby VM
> and the native code (that is part of the design), but it won't always use
> the FFI gem. There is a native backend for JRuby-1.7+, and I am currently
> working on a native CRuby backend. There could also be a native backend
> for Topaz that uses ctypes (or whatever the RPython equivalent is).
Thanks. It sounds intruiging and I'm looking forward to digging into XNI and ffi-compiler.
Awhile ago I'd looked into go's interop, python's cffi+libffi+pycparser+ply, luajit's ffi, and powershell's ability to intfc to Win32 via .NET's interop magic. While I liked the idea of copy-n-pasting normal C declarations as in the luajit and cffi simple examples
# luajit
local ffi = require("ffi")
ffi.cdef[[
int printf(const char *fmt, ...);
]]
# python cffi
from cffi import FFI
ffi = FFI()
ffi.cdef("""
int printf(const char *fmt, ...);
""")
I had a gut feeling that the extra complexity of implementing/maintaining C declaration parsing code may not be worth it. Given the types of setup questions on this list, and the setup info on the FFI wiki pages, what's your XNI perspective?
Jon
---
Fail fast. Fail often. Fail publicly. Learn. Adapt. Repeat.
http://thecodeshop.github.com | http://jonforums.github.com/
twitter: @jonforums--
---
You received this message because you are subscribed to the Google Groups "ruby-ffi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-ffi+u...@googlegroups.com .
For more options, visit https://groups.google.com/groups/opt_out .
--Jeremy Voorhis