How to pass a lostanza callback to a C function?

39 Views Asked by At

I wish to pass a lostanza function to a C API, where it will be called from C.

This is my current implementation :

; callbacks.stanza
defpackage callbacks : 
  import core

extern call_from_c : (ptr<(() -> int)>) -> int
lostanza defn my-callback () -> int : 
  return 42

lostanza defn call-from-c () -> ref<Int> : 
  val ret = call-c call_from_c(addr(my-callback))
  return new Int{ret}

println(call-from-c())

With corresponding C file :

// call_from_c.c
int call_from_c (int (*callback)()) {
    return callback();
}

I compile this code with stanza callbacks.stanza -ccfiles call_from_c.c -o cbk, but when running it I get this error message :

$ ./cbk 
FATAL ERROR: Stack overflow
  in core/fatal!
    at core/core.stanza:374.2
  in core/extend-stack
    at core/core.stanza:2438.9
Segmentation fault (core dumped)

What do I need to be doing in order to set up the call to lostanza from C?

1

There are 1 best solutions below

0
On

You're basically almost there. The one change you need is to change lostanza defn my-callback to extern defn my_callback.

There are two changes in there:

  1. You extern defn to signal that this function is meant to be called using the C calling convention, instead of the standard Stanza convention.

  2. The name got changed to my_callback. This is because the Stanza compiler will generate an assembly function that can be called from C for extern defn definitions. And since C does not allow hyphens in names, that means that you have to use an underscore instead.