Subject:
Re: [ruby-ffi] I wrote on advanced FFI usage
From:
Wayne Meissner
Date:
3/29/13 6:53 PM
To:
ruby-ffi@googlegroups.com

There are a few other tricks you can do:

1) Use as a result filter to automagically turn errno values into exceptions (not that I recommend exceptions-as-flow-control)
e.g.
    module PosixResult
      extend FFI::DataConverter
      native_type FFI::Type::INT

      def self.from_native(value, ctx)
        if value != -1
          value
        else
          raise SystemCallError.new("native error", FFI.errno)
        end
      end
    end

    attach_function :some_function_that_can_fail, [  ], PosixResult

2) Automagically convert and free pointer results.  
e.g. lets say you have a function that returns an allocated C string, and you need to free it yourself.  You /could/ use an AutoPointer, but to be kinder to the GC, you want to copy the string immediately to a GC managed object, and free the underlying C string.

    class AllocatedStringResult
      extend FFI::DataConverter
      native_type FFI::Type::POINTER

      def self.from_native(val, ctx)
        if val.null?
          nil
        else 
          str = val.get_string(0)
          LibC.free(val)
          str
        end
      end
  end

3) Any subclass of FFI::AutoPointer can be used as a function result, and it automatically wraps the result of the function in that AutoPointer subclass. 

You could also make something like this work:

    attach_function :some_function, [], Device.managed

that way, Device is a regular non-autopointer, except in those cases where you need it to be.  Look at Struct.auto_ptr for ideas on how to implement Device.managed.

4) Completely replace the FFI api with your own concoction.  Using FFI::DynamicLibrary, FFI::Function, and FFI::DataConverter, you can write your own API for mapping C libraries into ruby.  Thats how JRuby implements legacy interfaces like dl and Win32API.


On Saturday, 30 March 2013 08:44:29 UTC+10, Postmodern wrote:
Thank you for putting this together. I was meaning to write a more
details overview of FFI; all of the other blog posts only cover loading
a library and attaching some functions. I never knew about by_ref and
extending FFI::Pointer is brilliant.

On 03/28/2013 11:34 AM, Kim Burgestrand wrote:
> Might be interesting to you since you are subscribed to the FFI
> mailing list. The article is
> here: http://www.elabs.se/blog/61-advanced-topics-in-ruby-ffi
>
> If you have any reactions to what I've written I'd love to hear them.
>
>
>
> --
> — Kim Burgestrand
> --
>  
> ---
> 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.
>  
>  


--
Blog: http://postmodern.github.com/
GitHub: https://github.com/postmodern
Twitter: @postmodern_mod3
PGP: 0xB9515E77


--
 
---
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.