# Ctypes - how to cast a function pointer and then call it?

**URL:** <https://discuss.ocaml.org/t/ctypes-how-to-cast-a-function-pointer-and-then-call-it/9653>\
**Category:** Ecosystem\
**Tags:** ctypes\
**Created:** [April 7, 2022, 10:27am UTC](https://discuss.ocaml.org/t/ctypes-how-to-cast-a-function-pointer-and-then-call-it/9653 "2022-04-07T10:27:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mhouh](https://avatars.discourse-cdn.com/v4/letter/m/838e76/32.png) [@Mhouh](https://discuss.ocaml.org/u/Mhouh)\
**Post date:** [April 7, 2022, 10:27am UTC](https://discuss.ocaml.org/t/ctypes-how-to-cast-a-function-pointer-and-then-call-it/9653/1 "2022-04-07T10:27:50Z")

</div>

To provide a simple example imagine we have a Simplistic C library:

```auto
typedef void (*void_function)(void);
typedef int (*adder)(int, int);
int add(int a, int b){ return a + b; }
void_function load(void){
        return (void_function)add;
}

```

I can bind `load` with Ctypes using  
`let load = foreign "load" (Ctypes.void @-> returning Types.void_function)`  
where `void_function` is defined in the types pass as a (unit → unit) (I’m using the new dune ctypes stanza)  
But now, I would like to “cast” the (unit → unit) function pointer I get when calling load to it’s actual type, (int → int → int) and call it in my ocaml code.  
How to achieve this? Using coerce\_fn should’nt work, as they do not have the same arity…  
To use `coerce`, I need to be in the function pass, but I also need to use `load` which isn’t available until function pass is complete… I feel stuck.

I’m new here, so feel free to tell me if I missed something 🙂

---

<div class="post-metadata">

**Author:** ![thierry-martinez](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thierry-martinez/32/1481_2.png) [@thierry-martinez](https://discuss.ocaml.org/u/thierry-martinez)\
**Post date:** [April 7, 2022, 10:16pm UTC](https://discuss.ocaml.org/t/ctypes-how-to-cast-a-function-pointer-and-then-call-it/9653/2 "2022-04-07T22:16:57Z")

</div>

Disclaimer: I am a complete beginner in `ctypes` and I would be very interested if you could share your `dune` file showing how you use the `ctypes` stanza!

Could you show how `void_function` is defined in the type description module? I would suggest to use the following definitions:

```ocaml
let void_function = static_funptr (void @-> returning void)

let adder = static_funptr (int @-> int @-> returning int)

```

you can then coerce `load`'s result between the two types:

```ocaml
let add = coerce Types.void_function Types.adder (load ())

```

and call `add` by coercing it to `Foreign.funptr`:

```ocaml
let () =
  Format.eprintf "%d@."
    (coerce Types.adder (Foreign.funptr (int @-> int @-> returning int)) add 1 2)

```

---

<div class="post-metadata">

**Author:** ![Mhouh](https://avatars.discourse-cdn.com/v4/letter/m/838e76/32.png) [@Mhouh](https://discuss.ocaml.org/u/Mhouh)\
**Post date:** [April 8, 2022, 12:31pm UTC](https://discuss.ocaml.org/t/ctypes-how-to-cast-a-function-pointer-and-then-call-it/9653/4 "2022-04-08T12:31:56Z")

</div>

Got it working, thanks to @thierry-martinez 's answer!  
If that might be helpful for someone, or even future me, here is a detailed test setup on a simple example library.

It’s header:

- **/usr/include/my\_test.h** :

```auto
typedef void(*function_pointer)(void);
function_pointer load(char *name);

```

- **my\_test.c** (used to generate /usr/lib/libmy\_test.so):

```auto
#include<stdio.h>
#include<string.h>
#include"my_test.h"
typedef int(*int_binary_opperator)(int, int);
typedef void(*function_pointer)(void);
int add(int a, int b){
        printf("in C: a = %d, b = %d, add(a, b) = %d\n", a, b, a + b);
        return a + b;
}
function_pointer load(char *name){
        if(!strcmp(name, "add")) return (function_pointer)add;
        else return NULL;
}

```

I set that up with (please be careful not breaking your system):

```auto
sudo gcc -Wall -Wextra -Werror -fpic -o my_test.o -c my_test.c
sudo gcc -shared -o libmy_test.so my_test.o
sudo cp my_test.h /usr/include/
sudo cp libmy_test.so /usr/lib/

```

Now the library is ready for binding!

Dune now accepts ctypes stanza, that does the generation steps for you.  
I used that AND Foreign, because I only get the pointer at execution time.  
The **dune** file:

```auto
(executable
  (name main)
  (libraries ctypes ctypes.foreign)
  (flags (:standard -w -9-27))
  (ctypes
    (external_library_name my_test)
    (headers (include "/usr/include/my_test.h"))
    (type_description
      (instance Type)
      (functor Type_description))
    (function_description
      (instance Function)
      (functor Function_description))
    (generated_entry_point C)))

```

Very similar to the “Toy example” in [Dealing with Foreign Libraries — Dune documentation](https://dune.readthedocs.io/en/stable/foreign-code.html?highlight=ctypes#a-toy-example).  
It uses 2 functors,

1. **type\_description.ml** :

```auto
module Types(T : Ctypes.TYPE) = struct
  let function_pointer_type = T.(void @-> returning void)
  let binary_operator_type = T.(int @-> int @-> returning int)
  let function_pointer = T.(static_funptr function_pointer_type)
  let binary_operator = T.(static_funptr binary_operator_type)
end

```

1. **function\_description.ml** :

```auto
module Types = Types_generated
module Functions(F : Ctypes.FOREIGN) = struct
  let load = F.(foreign "load" (Ctypes.string @-> returning Types.function_pointer))
end

```

note that previous module is available as Types\_generated.

Now, I use that in **main.ml** :

```auto
let pointer = C.Function.load "add"
let adder =
  Ctypes.coerce
    C.Type.function_pointer
    (Foreign.funptr C.Type.binary_operator_type)
    pointer
let a, b = 7, 11
let result = adder a b
let () = Printf.printf "ocaml side: a = %d, b = %d, add a b = %d\n" a b result

```

The module C (generated, and named like so in **dune** ) contains Type and Function, each containing related definitions.

output of `dune ./main.exe`:

> in C: a = 7, b = 11, add(a, b) = 18  
> ocaml side: a = 7, b = 11, add a b = 18

I think it is mandatory to use Foreign in the main, as the pointer is retrieved and cast at run time. If someone can confirm this, or correct me if I am wrong, you are more than welcome!  
On another note, I wonder if performance might be an issue with function pointers loaded at run time and used via ocaml…

---

<div class="post-metadata">

**Author:** ![Mhouh](https://avatars.discourse-cdn.com/v4/letter/m/838e76/32.png) [@Mhouh](https://discuss.ocaml.org/u/Mhouh)\
**Post date:** [April 8, 2022, 12:53pm UTC](https://discuss.ocaml.org/t/ctypes-how-to-cast-a-function-pointer-and-then-call-it/9653/5 "2022-04-08T12:53:29Z")

</div>

> [@thierry-martinez](#):
>
> disclaimer: I am a complete beginner in `ctypes`

does not feels like so 😁
