From 27d03c4fb2eaedc0475d19cf94cb0485aec972ba Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 6 Jun 2021 16:01:35 -0700 Subject: ffi: allow nil object to convert under closure type. * ffi.c (ffi_closure_put): Only diagnose a bad object if it's not nil, otherwise let the null value of p through. This is useful because there are sometimes C interfaces which take an optional function pointer, whereby a null value indicates that the pointer is not specified. --- ffi.c | 2 +- txr.1 | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/ffi.c b/ffi.c index 25d8a8d5..7c001187 100644 --- a/ffi.c +++ b/ffi.c @@ -2142,7 +2142,7 @@ static void ffi_closure_put(struct txr_ffi_type *tft, val ptr, mem_t *dst, } else if (type == ffi_closure_s) { struct txr_ffi_closure *tfcl = ffi_closure_struct(ptr); p = tfcl->fptr; - } else { + } else if (ptr != nil) { uw_throwf(error_s, lit("~a: ~s cannot be used as function pointer"), self, ptr, nao); } diff --git a/txr.1 b/txr.1 index 58439d26..72cff575 100644 --- a/txr.1 +++ b/txr.1 @@ -73233,11 +73233,29 @@ the foreign function alters the pointer. .coNP FFI type @ closure The .code closure -type converts two kinds of Lisp objects to a C pointer: the +type converts three kinds of Lisp objects to a C pointer: the object +.codn nil , +the .code cptr -type, and the special +type, or the special .code ffi-closure -type, whose instances are produced by the +type. + +When the +.code nil +symbol is converted to a +.code closure +type, it becomes a null function pointer. + +A +.code cptr +object of any kind converts to a +.codn closure ; +the internal pointer is converted to a function pointer. + +Instances of the +.code ffi-closure +type are produced by the .code ffi-make-closure function, or by calls to functions defined by the .code deffi-cb @@ -73246,6 +73264,15 @@ macro. The type is useful for passing callbacks to foreign functions: Lisp functions which appear to be C functions to foreign code. +In the reverse direction, when a +.code closure +object is converted from the foreign function pointer representation +to a Lisp object, it becomes a +.code cptr +object whose tag is the +.code closure +symbol. + .coNP FFI type @ void The .code void -- cgit v1.2.3