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