Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Racket FFI: C function which accepts a pointer to a function

Tags:

racket

ffi

I'd like to bind to a C function abc whose signature is:

int abc(void (*)(int))

I.e. it accepts a pointer to a function. This callback accepts an int and has void return type.

What's the right incantation in Racket?

like image 456
dharmatech Avatar asked Mar 23 '23 15:03

dharmatech


1 Answers

Here is an example for a similar binding: let's say that we want to bind a function callTwice with the signature:

int callTwice(int (*)(int));

and with the silly C implementation:

int callTwice(int (*f)(int)) {
  return f(f(42));
}

Here's what the Racket FFI binding looks like:

(define call-twice (get-ffi-obj "callTwice" the-lib
                                (_fun (_fun _int -> _int) -> _int)))

where the-lib is the FFI-bound library we get from ffi-lib. Here, we see that the first argument to call-twice is itself a (_fun _int -> _int), which is the function pointer type we want for my example.

That means that technically we could have written this:

(define _mycallback (_fun _int -> _int))

(define call-twice (get-ffi-obj "callTwice" the-lib
                                (_fun _mycallback -> _int)))

to make it easier to see that call-twice takes in a callback as its only argument. For your case, you'll probably want (_fun _int -> _void) for the value of your callback type.

The fully worked-out example can be found here: https://github.com/dyoo/ffi-tutorial/tree/master/ffi/tutorial/examples/call-twice. Run the pre-installer.rkt in that directory to build the extension, and then test it out by running test-call-twice.rkt.

like image 111
dyoo Avatar answered Apr 26 '23 16:04

dyoo