ffi, struct pointer question

D

Daniel Berger

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
 
T

Thomas Chust

2009/8/2 Daniel Berger said:
[...]
=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.
 
D

Daniel Berger

2009/8/2 Daniel Berger <[email protected]>:


[...]
=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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top