Subject:
[ruby-ffi] Re: **char issues
From:
Wayne Meissner
Date:
10/30/09 10:24 AM
To:
ruby-ffi@googlegroups.com


2009/10/31 Bryan Kearney <bkearney@redhat.com>:
> Thank you.. that worked. Next one is a ***char issue. the augeas API returns
> an array of Strings:
>
> int aug_match(const augeas *aug, const char *path, char ***matches);
>
> I have mapped it as
>
>  attach_function :aug_match, [:pointer, :string, :pointer], :int
>
> and I am trying to call it. I have 2 tries:
>
>
>    def match2(path)
>        self.check()
>        ptr = FFI::MemoryPointer.new(:pointer, 1)
>        len = AugeasLib.aug_match(@aug, path, ptr)
>        puts(len)
>        strPtr = ptr.read_pointer()
>        strPtr.null? ? [] : strPtr.read_array_of_type(:string, :read_pointer,
> len)
>    end

You should be able to replace the last line of that with:

  strPtr.null ? [] : strPtr.get_array_of_string(0, len).compact

get_array_of_string() will read len pointers, converting each either
to a string, or to nil if the pointer is NULL.  Array#compact then
removes any nil values from the array.

Your match() function probably should have used the triple-dot range:

(0...len)

i.e. 0 up to, but not including len.  You would have been reading one
pointer element beyond the end of the array, and quite possibly read a
garbage value and tried to deref it.  (trying to deref a NULL value
will get you a ruby exception, but there's nothing we can do about
invalid non-zero memory locations).