# Strange error when calling external c functions

**URL:** <https://discuss.ocaml.org/t/strange-error-when-calling-external-c-functions/5777>\
**Category:** Learning\
**Tags:** ffi\
**Created:** [May 15, 2020, 5:02pm UTC](https://discuss.ocaml.org/t/strange-error-when-calling-external-c-functions/5777 "2020-05-15T17:02:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![thautwarm](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thautwarm/32/1455_2.png) [@thautwarm](https://discuss.ocaml.org/u/thautwarm)\
**Post date:** [May 15, 2020, 5:02pm UTC](https://discuss.ocaml.org/t/strange-error-when-calling-external-c-functions/5777/1 "2020-05-15T17:02:57Z")

</div>

I’m trying to call Python’s C APIs in OCaml efficiently.

```auto
external pyinit : unit -> unit = "Py_Initialize"
external errprint : unit -> unit = "PyErr_Print"
external compile : string -> string -> int -> pyo = "Py_CompileString"

let main() =
  let _ = pyinit() in
  let _ = compile "print(1)" "a.py" 257 in
  errprint()

sh> dynjit dune exec myproj
  File "a.py", line 1
    print(1)
    ^
SyntaxError: invalid syntax

```

This is really a strange error, everything is fine but it doesn’t work.

I’ve tried invoking the C function `Py_CompileString` in Python with python’s ctypes, it works.  
Also I’ve tried this in another programming language with its dynamic link interfaces, things also work.

However the equivalent code in OCaml causes this very strange error. The c function arguments must be handled correctly otherwise I cannot see “print(1)” or “a.py” in the error report.

If I incorrectly put the whitespaces in the head of the code, `err_print` can also report what the syntax error is.

So strange… Any suggestions?

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [May 15, 2020, 7:30pm UTC](https://discuss.ocaml.org/t/strange-error-when-calling-external-c-functions/5777/2 "2020-05-15T19:30:09Z")

</div>

You are lucky your code doesn’t segfault : )

When OCaml calls a C function, it generally needs to go through a wrapper function in order to handle the interaction with OCaml’s GC and the conversion between C and OCaml data types.

In particular, `external` is expected to be used only for functions that have specific signatures and follow specific conventions, and **it is not meant** as a general way to call arbitrary C functions.

You can learn more about the OCaml/C FFI by heading over to [https://caml.inria.fr/pub/docs/manual-ocaml/intfc.html](https://caml.inria.fr/pub/docs/manual-ocaml/intfc.html).

Luckily for you, OCaml has a version of `ctypes` which works very well. You should be able to use to call the Python API functions. Head over [https://github.com/ocamllabs/ocaml-ctypes](https://github.com/ocamllabs/ocaml-ctypes) to learn more about it.

Cheers,  
Nicolás

---

<div class="post-metadata">

**Author:** ![thautwarm](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thautwarm/32/1455_2.png) [@thautwarm](https://discuss.ocaml.org/u/thautwarm)\
**Post date:** [May 16, 2020, 1:29am UTC](https://discuss.ocaml.org/t/strange-error-when-calling-external-c-functions/5777/3 "2020-05-16T01:29:49Z")

</div>

Thanks a lot for posting these references and giving me suggestions.

I don’t want to use ctypes because my application is performance sensitive, actually it’s for generally speed up python programs, so ocaml-ctypes are quite slow here. Although there is a cstubs approach by ocaml-ctypes which is much faster, I tried pyml(they said it’s implemented via cstubs) but still the performance didn’t satisfy me.  
I know how to write wrappers and make custom primitives, but I don’t want to write lots of c code.  
Also there’re many C APIs, if I can directly use external functions, I’d feel satisfied…

> [@nojb](#):
>
> only for functions that have specific signatures and follow specific conventions, and **it is not meant** as a general way to call arbitrary C functions.

I now successfully workaround things, by making only one c function to right shift interger 1 bit(nativeint and int32 requires manual wrapper)… and I can keep my types used in external functions always a subset of `{int64, int, string, unit, i32}` where i32 is just an opaque type for representing c int.

Is this okay to directly call those external functions? It seems things work fine now.

Besides, I feel so eager that I want to know all details about external keyword…  
It seems the documentation just lists a few extensions (`[@@unboxed|`, etc.), not very clean as well. And their corresponding syntax before 4.03.0(I’m using modular-implicits) is also hard to find in the documentations available online.

Cheers,  
Taine
