ffi, struct pointer question

Discussion in 'Ruby' started by Daniel Berger, Aug 2, 2009.

  1. Hi,

    I've recently been trying to port some C code over to FFI. I'm trying
    to figure out how to unravel the gr_mem group struct member. Any
    suggestions?

    require 'ffi'

    module Sys
    class Admin
    extend FFI::Library

    class GroupStruct < FFI::Struct
    layout(
    :gr_name, :string,
    :gr_passwd, :string,
    :gr_gid, :int,
    :gr_mem, :pointer
    )
    end

    attach_function :getgrgid, [:int], :pointer

    def self.get_group(gid)
    GroupStruct.new(getgrgid(gid))
    end
    end
    end

    # How do I unravel the gr_mem struct member?
    struct = Sys::Admin.get_group(84)
    p struct[:gr_mem]

    Regards,

    Dan
     
    Daniel Berger, Aug 2, 2009
    #1
    1. Advertising

  2. Daniel Berger

    Thomas Chust Guest

    2009/8/2 Daniel Berger <>:
    > [...]
    > =A0 =A0 =A0class GroupStruct < FFI::Struct
    > =A0 =A0 =A0 =A0 layout(
    > [...]
    > =A0 =A0 =A0 =A0 =A0 =A0:gr_mem, =A0 =A0:pointer
    > =A0 =A0 =A0 =A0 )
    > =A0 =A0 =A0end
    >
    > =A0 =A0 =A0attach_function :getgrgid, [:int], :pointer
    >
    > =A0 =A0 =A0def self.get_group(gid)
    > =A0 =A0 =A0 =A0 GroupStruct.new(getgrgid(gid))
    > =A0 =A0 =A0end
    > [...]
    > # How do I unravel the gr_mem struct member?
    > struct =3D Sys::Admin.get_group(84)
    > p struct[:gr_mem]


    Hello,

    the gr_mem member of the group structure is a NULL terminated array of
    zero terminated strings, so you need to read all the string pointers
    from the array until you encounter a null pointer and then read the
    string data from each string pointer.

    I would suggest the use of an auxiliary method, which could actually
    be added to the FFI::pointer class for convenience:

    class FFI::pointer
    def read_string_array_to_null()
    elements =3D []

    psz =3D self.class.size
    loc =3D self
    until ((element =3D loc.read_pointer).null?)
    elements << element.read_string_to_null
    loc +=3D psz
    end

    elements
    end
    end

    Using this method, you can unravel the mysterious pointer member as follows=
    :

    p struct[:gr_mem].read_string_array_to_null

    ;-)


    I hope that helps,
    Thomas


    --=20
    When C++ is your hammer, every problem looks like your thumb.
     
    Thomas Chust, Aug 2, 2009
    #2
    1. Advertising

  3. On Aug 2, 6:13=A0am, Thomas Chust <> wrote:
    > 2009/8/2 Daniel Berger <>:
    >
    >
    >
    > > [...]
    > > =A0 =A0 =A0class GroupStruct < FFI::Struct
    > > =A0 =A0 =A0 =A0 layout(
    > > [...]
    > > =A0 =A0 =A0 =A0 =A0 =A0:gr_mem, =A0 =A0:pointer
    > > =A0 =A0 =A0 =A0 )
    > > =A0 =A0 =A0end

    >
    > > =A0 =A0 =A0attach_function :getgrgid, [:int], :pointer

    >
    > > =A0 =A0 =A0def self.get_group(gid)
    > > =A0 =A0 =A0 =A0 GroupStruct.new(getgrgid(gid))
    > > =A0 =A0 =A0end
    > > [...]
    > > # How do I unravel the gr_mem struct member?
    > > struct =3D Sys::Admin.get_group(84)
    > > p struct[:gr_mem]

    >
    > Hello,
    >
    > the gr_mem member of the group structure is a NULL terminated array of
    > zero terminated strings, so you need to read all the string pointers
    > from the array until you encounter a null pointer and then read the
    > string data from each string pointer.
    >
    > I would suggest the use of an auxiliary method, which could actually
    > be added to the FFI::pointer class for convenience:
    >
    > =A0 =A0 =A0 =A0 class FFI::pointer
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 def read_string_array_to_null()
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 elements =3D []
    >
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 psz =3D self.class.size
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 loc =3D self
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 until ((element =3D loc.r=

    ead_pointer).null?)
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 elements =

    << element.read_string_to_null
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 loc +=3D =

    psz
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end
    >
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 elements
    > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end
    > =A0 =A0 =A0 =A0 end
    >
    > Using this method, you can unravel the mysterious pointer member as follo=

    ws:
    >
    > =A0 =A0 =A0 =A0 p struct[:gr_mem].read_string_array_to_null
    >
    > ;-)
    >
    > I hope that helps,
    > Thomas


    Thank you for that Thomas, it worked great.

    I also found nice-ffi, and I suspect it may have some convenient way
    of doing what you're doing there, only I don't see it.

    http://github.com/jacius/nice-ffi/tree/master

    Regards,

    Dan
     
    Daniel Berger, Aug 2, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. beetle
    Replies:
    2
    Views:
    913
    beetle
    Jan 25, 2005
  2. Zero
    Replies:
    16
    Views:
    661
    Barry Schwarz
    Nov 19, 2005
  3. Daniel Berger

    FFI, sysctl, pointer question

    Daniel Berger, Aug 7, 2009, in forum: Ruby
    Replies:
    5
    Views:
    174
    Daniel Berger
    Aug 7, 2009
  4. John Croisant
    Replies:
    0
    Views:
    102
    John Croisant
    Oct 25, 2009
  5. aleksa

    Struct pointer vs. struct array pointer

    aleksa, Feb 20, 2013, in forum: C Programming
    Replies:
    16
    Views:
    472
    Shao Miller
    Feb 20, 2013
Loading...

Share This Page