[gambit-list] C-FFI pointers in c function arguments
    Marc Feeley 
    feeley at iro.umontreal.ca
       
    Fri Nov 19 09:43:32 EST 2010
    
    
  
On 2010-11-19, at 3:06 AM, Sid H wrote:
> Hi,
> 
> I'm just starting with the FFI. I'm trying to call a C function that updates a
> pointer argument. However, that value does not seem to change.
> 
> My understanding is that all arguments passed to C are treated as immutable. So,
> if we need to return any value from C then, it cannot be via an argument only.
> Is that correct? Please see my example below.
> ...
You are not obeying the API of the get_value function, which expects an int* parameter.  You need to supply a pointer to a C allocated "int".  Here's how I would do it.
Marc
;;;------------------------------------------------
;; Functions on int* type.
(c-declare #<<c-declare-end
#include <stdlib.h>
int *new_int()
{
  printf("new_int\n");
  return (int*)malloc(sizeof(int));
}
___SCMOBJ free_int(void *ptr)
{
  printf("free_int\n");
  free(ptr);
  return ___NO_ERR;
}
int get_int(int *ptr) { return *ptr; }
void set_int(int *ptr, int val) { *ptr = val; }
c-declare-end
)
(c-define-type int* (nonnull-pointer int (int*)))
(c-define-type int*/free (nonnull-pointer int (int*) "free_int"))
(define new-int (c-lambda () int*/free "new_int"))
(define get-int (c-lambda (int*) int "get_int"))
(define set-int (c-lambda (int* int) void "set_int"))
(define (test)
  (let ((p (new-int)))
    (set-int p 123)
    (pp (get-int p))
    (set-int p 999)
    (pp (get-int p))
    (set! p 'foo)
    (##gc))) ;; object allocated by new-int will be freed
;;;------------------------------------------------
(c-declare #<<c-declare-end
#include <stdio.h>
int get_value(int* value)
{
  *value = 42;
   return 21;
}
c-declare-end
)
(define get-value (c-lambda (int*) int "get_value"))
(define value (new-int))
(set-int value 99999)
(println (get-int value))
(let ((retval (get-value value)))
  (if (= retval 21)
      (println value)
      (println "Did not get 21 as return value")))
(println (get-int value))
;; will print:
;;
;; new_int
;; 99999
;; #<int* #2 0x100502740>
;; 42
;; free_int
;;;------------------------------------------------
    
    
More information about the Gambit-list
mailing list