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

From: Eli Barzilay (eli at barzilay.org)
Date: Wed Jun 24 03:34:39 EDT 2009

On Jun 23, scott wrote:
> 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 [...]

There are several problems in this code.  I don't have that library,
so I needed to define the struct myself, there were some typing
issues, and alloc_marker() did not put the allocated pointer in the
pointer it received.  The scheme code had some issues too, like
calling the function `alloc_test_from_scheme'.

But it looks to me like the core of your problem is here:

> ;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))))


You're passing a newly allocation pointer that points to your pointer,
but display_pointer() expects to get just your pointer.  One solution
is to change display_pointer() to expect a pointer to a pointer.
Another solution is to fix the scheme code to follow the C type, and
this is what I did below.


----------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>

struct st_marker {
  long timestamp;
  int  offset;
  int  value;
  void *next;
};

int display_pointer(struct st_marker *marker) {
  fprintf(stderr,"marker: %p, timestamp: %ld\n", marker, marker->timestamp);
  return 0;
}

int alloc_marker(struct st_marker **marker) {
    *marker = (struct st_marker *) malloc(sizeof (struct st_marker));
    (*marker)->timestamp = 1000;
    fprintf(stderr, "allocated new ");
    display_pointer(*marker);
    return 0;
}
----------------------------------------------------------------------
#lang scheme
(require scheme/foreign)
(unsafe!)

(define-cstruct _st_marker
  ([timestamp _long]
   [offset _int]
   [value _int]
   [next _st_marker/null]))

;int alloc_test_from_scheme(struct st_marker **marker_list);
(define alloc-marker
  (get-ffi-obj "alloc_marker" "./x.so"
               (_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" "./x.so"
               (_fun [marker : _st_marker-pointer/null]
                     -> [status : _int] -> (void))))

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

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the users mailing list.