Subject:
[ruby-ffi] Re: FFI core concepts wiki documentation
From:
Bryan Kearney
Date:
11/10/09 12:32 PM
To:
ruby-ffi@googlegroups.com


On 11/10/2009 12:19 PM, Jon wrote:

For me, it is about the examples. I would suggest adding some better
doco around passing items by reference and arrays. I admit I am weak at
C, so making the jump between a char*** and an array of strings was not
intuitive. The JNA website [1]  gives in doco examples to explain the

[1] https://jna.dev.java.net/#pointers

Agreed on the need for more examples.  It would be great if you could summarize your recent augeas char** and char*** discussions into an example and update the wiki.


Let me write up what I did, and if it is the best practice I will be happy to add to the wiki. These examples are from the augeas.h file which can be seen at [1]


Passing a Single String by Reference
-------------------------------------

Assume the method:
    int aug_get(const augeas *aug, const char *path, const char **value);

Where value is a a pointer to a String which is returned. This was mapped using the following:

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

And the code which uses this function is shown below:

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

Passing an Array of Strings back by Reference
----------------------------------------------

int aug_match(const augeas *aug, const char *path, char ***matches);

Where matches is an array of strings returned by reference, and the return code of the method is the length of the array. This is mapped to ffi using:

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

And the code which calls this function is:

    def match(path)
        check()
        ptr = FFI::MemoryPointer.new(:pointer, 1)
        len = AugeasLib.aug_match(@aug, path, ptr)
        if (len < 0)
            raise SystemCallError.new("Matching path expression '#{path}' failed")
        else
            strPtr = ptr.read_pointer()
            strPtr.null? ? [] : strPtr.get_array_of_string(0, len).compact
        end
    end

[1] http://bit.ly/iT6uY