[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