Forum: Ruby Using FFI or Fiddle on an Embedded Ruby

0814ff69e309b033508b3c7f363236fd?d=identicon&s=25 Ian Trudel (backorder)
on 2017-03-20 16:50
I would like to be able to pass Ruby varargs as an argument to a C
function created with rb_define_method. The typical prototype for a C
function with argc = -1 is VALUE func(int argc, VALUE *argv, VALUE obj).

The following is a code sample that would be representative of the
situation but yet would work with a standard Ruby.

########
require("fiddle")
require("fiddle/import")

module EmbeddedRuby
   extend Fiddle::Importer
   dlload("msvcrt-ruby220.dll")

   typealias "VALUE", "unsigned long"

   extern "VALUE rb_ary_cat(VALUE, const VALUE *, long)"
end

a = [ "a", "b", "c" ]
b = ["d", "e", "f"]

puts a.dup.push(b).inspect
puts a.dup.push(*b).inspect

puts Fiddle::Pointer.new(
         EmbeddedRuby.rb_ary_cat(
            Fiddle::Pointer.new(a.__id__ << 1),
            Fiddle::Pointer.new(b.__id__ << 1).ref,
            b.size)).to_value.inspect
########

The Ruby script outputs the following on Ruby 2.2.6:

["a", "b", "c", ["d", "e", "f"]]
["a", "b", "c", "d", "e", "f"]
["a", "b", "c", ["d", "e", "f"], false, false]

The expected results would be ["a", "b", "c", "d", "e", "f"]. Anyone
knows how to do this with either Fiddle or FFI (or both)?
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.