Help with basic ffi and define-external callback
Paul Wisehart via Chicken-users <[email protected]> Fri, 10 Apr 2026 18:03:52 -0400
| Newsgroups | gmane.lisp.scheme.chicken |
|---|---|
| Message-ID | <[email protected]> |
Hi!
I have been using basic ffi successfully.
Now I am trying to level up and call a scheme
defined function from C.
I am looking here:
https://wiki.call-cc.org/man/5/Module%20(chicken%20foreign)#callbacks
I set up a basic example here:
https://codeberg.org/pkw/chicken-learn/src/branch/main/c-callbacks
-------------
I am trying it in two ways and they both fail with:
home:~/code/scm/learn/c-callbacks$ ./main.exe fn1
fn1
Error: (location) bad argument type - locative cannot refer to objects of this type: #<procedure (interface#cb2)>
Call history:
main.scm:1: chicken.load#load-extension
main.scm:1: chicken.load#load-extension
main.scm:1: chicken.load#load-extension
interface.scm:6: chicken.load#load-extension
main.scm:24: main
main.scm:15: chicken.process-context#command-line-arguments
main.scm:17: scheme#display
main.scm:18: ##sys#check-output-port
main.scm:18: ##sys#print
main.scm:18: ##sys#make-locative
-------------
My scheme code looks like:
(define-external (cb1) void (display "cb1\n"))
(define-external (cb2) int 99)
(define-external (cstrl (c-string x)) int (string-length x))
(define fn1
(foreign-safe-lambda
int
"fn1"
int
c-pointer))
(define fn2
(foreign-safe-lambda
void
"fn2"
int
c-pointer))
-------------
My C code looks like: (i have a header file with the same signatures
but no var names on the definitions.)
#include "cinterface.h"
void
_f(void)
{
printf("_f\n");
}
int
fn1(int i, int ifn(int))
{
/* call a function pointer as a sanity check */
void (*f)(void);
f = _f;
f();
printf("fn1 i:%d\n", i);
return 66 + i;
}
void
fn2(int n, void (*f)(void))
{
(void) f;
printf("fn2 n:%d\n", n);
}
-------------
(define (usage)
(display "main.exe [fn1 fn2]\n"))
(define (main)
(match (command-line-arguments)
(("fn1")
(display "fn1\n")
(printf "fn1:~a~%" (interface:fn1 7 #$interface:cb2)))
(("fn2")
(display "fn2\n")
(interface:fn2 23 #$interface:cb1))
(_ (usage))))
(main)
-------------
Any ideas?
I am happy to try something or maybe if
this isn't clear I can try to say it differently.
Thanks!
--
Paul W