[plt-scheme] Re: passing pointer from one FFI call as input into another FFI call

From: scott (sshickey at qwest.net)
Date: Wed Jun 24 02:34:01 EDT 2009

Thanks for the quick reply. I think I'm close but not quite there
yet.The simple example below might help to show where my confusion in
accessing the pointer that's being pointed to.

Below are are two C functions - one that allocates memory and the
other takes a pointer to that memory. There's a little C test function
that shows typical use of these functions.

I would like to do something similar from PLT-Scheme. Thanks in
advance - this will really make my current life in C programming much
more interesting if I can at least write my test code in something
more interesting that C.

int alloc_marker(struct st_marker **marker) {
    struct st_marker *new_marker = (struct st_marker *) malloc(sizeof
(struct st_marker));
    *marker_list = new_marker;
    new_marker->timestamp = 1000;
    fprintf(stderr, "allocated new marker:%p , timestamp=%ld\n",
new_marker, new_marker->timestamp);
    return 0;
}

int display_pointer(struct st_marker *marker) {
  fprintf(stderr,"here is the address of the pointer passed in marker:
%p, timestamp:%ld\n", marker, marker->timestamp);
  fprintf(stderr,"*marker:%p\n",  *marker);

  return 0;
}

void ptr_test(CuTest *test_case) {
    struct st_marker *marker = NULL;
    alloc_test_from_scheme(&marker);
    CuAssertIntEquals(test_case, marker->timestamp, 1000);
    display_pointer(marker);
}

output from the above test (the first line represents how I expect to
use it):
allocated new marker:0x8540cd8 , timestamp=1000
here is the address of the pointer passed in marker:0x8540cd8,
timestamp:1000
*marker:0x3e8

In PLT-Scheme, I have the following functions defined:

;int alloc_test_from_scheme(struct st_marker **marker_list);
(define alloc-marker
  (get-ffi-obj "alloc_test_from_scheme" "libvfm"
               (_fun [marker : (_ptr o _st_marker-pointer/null)]
                     -> [status : _int] -> (values marker status))))

;int display_pointer(struct st_marker *marker);
(define display-pointer
  (get-ffi-obj "display_pointer" "libvfm"
               (_fun [marker : (_ptr i _st_marker-pointer/null)]
                     -> [status : _int] -> (values marker status))))

;; here's the test
(set!-values (marker status) (alloc-marker))
(display-pointer marker)

and the output:
allocated new marker:0x9877330 , timestamp=1000
here is the address of the pointer passed in marker:0xb5832c88,
timestamp:159871792
*marker:0x9877330




On Jun 19, 12:49 am, Eli Barzilay <e... at barzilay.org> wrote:
> On Jun 18, Scott Hickey wrote:
>
>
>
> > I have a C function that allocates a linked list of structs and it
> > works great until I try to pass it into another C function.
>
> > (define-cstruct _st_marker ([timestamp _int] [offset _int] [value
> > _int] [next _st_marker/null]))
>
> > ;; int get_markers(char *filename, struct st_marker **marker_list)
>
> > (define get-markers
> >   (get-ffi-obj "get_markers" "libvfm"
> >                (_fun _string [markers : (_ptr o _st_marker-pointer/
> > null)]
> >                      -> [status : _int] -> (values markers status))))
>
> > I want to pass the value returned in 'markers' above to the function
> > below:
>
> > ;; int create_event_list_from_marker_list(struct st_marker
> > *marker_list, struct st_event **event_list)
>
> > (define create-event-list-from-marker-list
> >   (get-ffi-obj "create_event_list_from_marker_list" "libvfm"
> >                (_fun [markers : (_ptr i _st_marker-pointer/null)]
> >                      [events : (_ptr o _st_event-pointer/null)]
> >                      -> [status : _int] -> (values events status))))
>
> > After searching for information on this, I saw on message that said
> > there are problems reusing the data bound using _ptr o  as input into
> > another C function. Is there a different syntax I can use to
> > accomplish this?
>
> It doesn't look like there should be a problem there -- you're using
> `_ptr o' which will allocate a pointer value, call the C function,
> then extract the value from that, so you're using the value that was
> pointed to (which in your case is also a pointer), not the temporary
> pointer that was passed out.
>
> --
>           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                  http://www.barzilay.org/                Maze is Life!
> _________________________________________________
>   For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme


Posted on the users mailing list.