mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
docs: Expands docs around C function pointers (#1038)
* docs: Generates HTML docs for Function core module * docs: Adds lifetime information in Function module * docs: Adds callback section to C Interop * docs: Corrects typos in Function docs
This commit is contained in:
parent
2a94f67db8
commit
ac4231d005
@ -1,7 +1,16 @@
|
||||
(defmodule Function
|
||||
(doc unsafe-ptr "returns void pointer to the function passed in."
|
||||
"This is unsafe as unsafe-ptr can't check the value passed in is a function.")
|
||||
(doc unsafe-ptr "returns a void pointer to the function passed in.
|
||||
|
||||
This is unsafe as unsafe-ptr can't check the value passed in is a function.
|
||||
|
||||
It is the responsibility of the caller to ensure that the lifetime of the pointer
|
||||
does not exceed the lifetime of the function it's used on.")
|
||||
(deftemplate unsafe-ptr (Fn [(Ref a)] (Ptr ())) "void* $NAME($a *fn)" "$DECL { return fn->callback; }")
|
||||
(doc unsafe-env-ptr "returns void pointer to the environment captured by a lambda."
|
||||
"This is unsafe as unsafe-env-ptr can't check the value passed in is a function.")
|
||||
|
||||
(doc unsafe-env-ptr "returns void pointer to the environment captured by a lambda.
|
||||
|
||||
This is unsafe as unsafe-env-ptr can't check the value passed in is a function.
|
||||
|
||||
It is the responsibility of the caller to ensure that the lifetime of the pointer
|
||||
does not exceed the lifetime of the function it's used on.")
|
||||
(deftemplate unsafe-env-ptr (Fn [(Ref a)] (Ptr ())) "void* $NAME($a *fn)" "$DECL { return fn->env; }"))
|
||||
|
@ -12,6 +12,7 @@ This is an extension of what is covered in the [Language Guide](./LanguageGuide.
|
||||
- [`deftemplate`](#deftemplate)
|
||||
- [`Basic example`](#basic-example)
|
||||
- [`Generics`](#generics)
|
||||
- [Callbacks](#callbacks)
|
||||
|
||||
|
||||
## How Carp generates identifiers
|
||||
@ -342,3 +343,44 @@ out/main.c:9153:29: error: invalid operands to binary expression ('String' (aka
|
||||
1 error generated.
|
||||
```
|
||||
|
||||
## Callbacks
|
||||
|
||||
Some C APIs rely on callbacks, let's define a C function that accepts a
|
||||
callback and an argument and returns the result of calling that function as an
|
||||
example:
|
||||
|
||||
```clojure
|
||||
(deftemplate runner (Fn [(Ptr ()) (Ptr ())] a)
|
||||
"$a $NAME(void* fnptr, void* args)"
|
||||
"$DECL {
|
||||
return (($a(*)(void*))fnptr)(args);
|
||||
}")
|
||||
|
||||
; Using a lambda capturing variables from its environment
|
||||
(let [x 20 y 22 fnfn (fn [] (+ @&x @&y))]
|
||||
(= (runner (Function.unsafe-ptr &fnfn) (Function.unsafe-env-ptr &fnfn))
|
||||
42))
|
||||
|
||||
; Using a static function
|
||||
(defn double [x] (Int.* @x 2))
|
||||
|
||||
(let [x 42]
|
||||
(= (runner (Function.unsafe-ptr &double) (Unsafe.coerce &x))
|
||||
84))
|
||||
```
|
||||
|
||||
In the first example we want to use a lambda capturing some variable, we can
|
||||
use `Function.unsafe-ptr` to get a `void*` to the function and in the case of
|
||||
lambdas capturing environment the first argument to that function is the
|
||||
environment so we have to use `Function.unsafe-env-ptr` to pass in that
|
||||
environment.
|
||||
|
||||
In the second example we want to use a static function so we can use
|
||||
`Function.unsafe-ptr` again, and the argument we pass in needs to be coerced
|
||||
from a `Ref` into a `(Ptr ())`.
|
||||
|
||||
Because everything gets turned into a void pointer all type safety is lost so
|
||||
it is the responsibility of the caller to ensure the operation is safe. It is
|
||||
also important to ensure the lifetime of the `Ptr` doesn't not exceed the
|
||||
lifetime of the function/env it represents.
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
Double
|
||||
Dynamic
|
||||
Float
|
||||
Function
|
||||
Geometry
|
||||
Int
|
||||
IO
|
||||
|
Loading…
Reference in New Issue
Block a user