Subject:
[ruby-ffi] Re: **char issues
From:
Bryan Kearney
Date:
10/30/09 9:46 AM
To:
ruby-ffi@googlegroups.com


On 10/28/2009 09:03 PM, Wayne Meissner wrote:

2009/10/29 bk<bkearney@redhat.com>:

I am attempting to convert the augeas bindings to ffi. I did this with
JNA, and it was very helpful. The method in question is:

int aug_get(const augeas *aug, const char *path, const char **value);

where the last paraemeter returns the result of the get. I have
attempted to wrap this with

  attach_function :aug_get, [:pointer, :string, :pointer], :int

and then call this with:

    def get(path)
        ptr = FFI::MemoryPointer.new(:pointer, 1)
        AugeasLib.aug_get(@aug, path, ptr)
        strPtr = ptr.read_pointer()
        return strPtr.read_string()
    end

This works fine if the get returns something, but if the get ruturns a
null string I fail with:

FFI::NullPointerError: invalid memory read at address=(nil)

You need to test strPtr for null
e.g.

   if !((strPtr = ptr.read_pointer).null?
     strPtr.read_string
   else
     ""  # Or whatever end value you want
   end
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

    def match(path)
        self.check()
        rv = []
        ptr = FFI::MemoryPointer.new(:pointer, 1)
        len = AugeasLib.aug_match(@aug, path, ptr)
        puts(len)
        strPtr = ptr.read_pointer()
        if (not (strPtr.null?))
            (0..len).each() do |x|
                rv << strPtr.get_pointer(x*FFI::Pointer.size()).read_string()
            end
        end
    end


match segfaults, and match2 results in:

test_basics(TestAugeas):
ArgumentError: Unknown native type
    /usr/lib/ruby/gems/1.8/gems/ffi-0.5.1/lib/ffi/types.rb:137:in `type_size'
    /usr/lib/ruby/gems/1.8/gems/ffi-0.5.1/lib/ffi/pointer.rb:76:in `read_array_of_type'
    /home/bkearney/code/ruby-augeas/lib/augeas.rb:167:in `match'
    ./tests/tc_augeas.rb:32:in `test_basics'



Is there an example which shows how to do this? Thanks!

-- bk