|Subject:||Re: [Chicken-users] #<invalid forwarded object> using FFI callback|
|Date:||Thu, 19 Dec 2013 21:15:21 +0100|
Did you find a solution to this problem? I seem to suffer a similar problem.
I'm encountering the following error message inside a callback using
Chicken's FFI interface:
Error: (cdr) bad argument type: #<invalid forwarded object>
pwent.scm:50: clist-append! <--
What seems to be happening is that I'm running out of (stack?) memory
while inside/around a C thunk. I cannot seem to avoid this message by
modifying the nursery, either from csc -nursery or from -:s.
I have only a topical grasp of Chicken's FFI, so I suspect I'm simply
doing something ill-advised, though I would appreciate advice on how
to approach my problem:
I'm trying to read /etc/passwd using getpwent(3) and store each
record returned in a scheme list. (My particular /etc/passwd file
contains <100 elements, the above error happens near the end of the
call.) I'm marshalling records using two callbacks: one to create the
memory for string data, and one to append each record to the list.
May I have feedback on the pattern I'm using here to marshall data?
And a suggestion on how to avoid invalid forward objects while
reading large but disjoint data from C? I'm at a loss as to why
exactly I'm getting the above message, and it well could be incorrect
code on my part. Do my multiple calls to _make_string from C,
below, cause the GC to loose track of my string pointers? Something
<++> csc -o pwent pwent.scm && ./pwent
; a circular list (where we track the
; head and tail) with a dummy head.
(let ((head (list #f)))
(cons head head)))
; O(1) list append.
(define (clist-append! d v)
(let ((l (list v)))
(set-cdr! (cdr d) l)
(set-cdr! d l)))
; return proper list
(define (clist->list d)
(cdr (car d)))
; allocate a scheme string available in C.
(_make_string (size_t n)) scheme-object
(declare (foreign-declare #<<EOF
; append! each pwent record to our record list.
(_getpwent_cb (scheme-object clist)
(scheme-object shell)) void
(let ((pwent `((user . ,user)
(passwd . ,passwd)
(uid . ,uid)
(gid . ,gid)
(home . ,home)
(shell . ,shell))))
(clist-append! clist pwent)))
; retrieve the next pwent record and marshall it
; in to scheme.
(foreign-safe-lambda* bool ((scheme-object clist)) #<<EOF
struct passwd *pw;
C_word shell, dir, passwd, name;
pw = getpwent();
n = strlen(pw->pw_name);
name = _make_string(n);
C_memcpy(C_c_string(name), pw->pw_name, n);
n = strlen(pw->pw_passwd);
passwd = _make_string(n);
C_memcpy(C_c_string(passwd), pw->pw_passwd, n);
n = strlen(pw->pw_dir);
dir = _make_string(n);
C_memcpy(C_c_string(dir), pw->pw_dir, n);
n = strlen(pw->pw_shell);
shell = _make_string(n);
C_memcpy(C_c_string(shell), pw->pw_shell, n);
; loop ever every entry in pwent and append
; it to our list.
(let loop ((clist (make-clist)))
(if (_getpwent clist)
$ csc -version
(c) 2008-2013, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 126.96.36.199 (stability/4.8.0) (rev 5bd53ac)
openbsd-unix-gnu-x86 [ manyargs dload ptables ]
compiled 2013-10-03 on aeryn.xorinia.dim (Darwin)
my personal website: http://c0redump.org/
Chicken-users mailing list
|[Prev in Thread]||Current Thread||[Next in Thread]|