Hi All,
Apologies for the fairly long question, I hope I'm not entirely on the
wrong path.
I'm trying to read a struct's members from a file in /proc (on
Solaris). Unfortunately some of the members of this struct are
actually typedef'd in header files meaning that cffi can not parse the
struct. It looks something like this:
typdef stuct psinfo {
pid_t pr_pid;
timestruct_t pr_start;
/* more fields here */
} psinfo_t;
As far as I understand the only way to really get to the fields in
psinfo_t is to write a separate function/library similar to this:
#include <sys/proc.h> /* declares psinfo_t, pid_t, etc. */
struct simple_psinfo {
long pr_pid;
long long pr_start_sec;
long long pr_start_nsec;
/* more fields here */
};
struct simple_psinfo*
read_psinfo(psinfo_t *psinfo)
{
struct simple_psinfo* simple;
simple = malloc(sizeof(struct simple_psinfo));
if (simple == NULL)
return NULL;
simple->pr_pid = (long)psinfo->pr_pid;
simple->ps_start_sec = (long long)psinfo->pr_start.tv_sec;
simple->ps_start_nsec = (long long)psinfo->pr_start_tv_nsec;
/* more fields here */
return simple;
}
Here the compiler would warn if I do a cast which does not work I
guess, solving the problem with not knowing the type. This is the
equivalent of the casts in PyLong_FromLong((long)psinfo->pr_pid) in
CPython's C API.
I think the corresponding cffi code to access this would then be:
ffi.cdef("""
typedef struct psinfo {
...
} psinfo_t;
struct simple_psinfo {
long pr_pid;
long long pr_start_sec;
long long pr_start_nsec;
/* more fields here */
};
struct simple_psinfo* read_psinfo(psinfo_t *psinfo);
""")
C = ffi.verify("""
#include <sys/proc.h>
""")
psinfo =
ffi.new('psinfo_t')
with open('data', 'rb') as fp:
fp.readinto(ffi.buffer(psinfo))
simple_psinfo = C.read_psinfo(psinfo)
print simple_psinfo.pr_pid
del simple_psinfo
So my questions are:
Firstly, is this the correct way of doing this?
If so, is it acceptable to move the read_psinfo function into the
ffi.verify() call? This would eliminate having to declare struct
simple_psinfo twice and having to do a bunch of stuff to build the
library, find it and pass it to cffi.
And finally, is there no way of doing this simpler? It would be nice
if cffi could deal with opaque types and ask the compiler to do the
casting. If there was some way to say "cast pid_t to long" then this
might be much simpler to do? I don't think it's possible to just
declare to the casted types directly in the struc psinfo of ffi.cdef()
is it?
Thanks,
Floris