SIGN IN SIGN UP
exaloop / codon UNCLAIMED

A high-performance, zero-overhead, extensible Python compiler with built-in NumPy support

0 0 2 Python
2025-07-12 12:43:17 -04:00
C/C++ functions can be called from Codon via the `from C import`
import statement. Unlike standard imports, `from C import` must
specify the imported function's argument and return types. For
example:
``` python
# import the C standard library 'sqrt' function
from C import sqrt(float) -> float
print(sqrt(2.0)) # 1.41421
```
You can also rename C-imported functions:
``` python
# cobj is a C pointer (void*, char*, etc.)
# None can be used to represent C's void
from C import puts(cobj) -> None as print_line
print_line("hello".c_str()) # prints "hello"; c_str() converts Codon str to C string
```
2025-07-13 11:27:01 -04:00
You can also add [annotations](../../language/llvm.md#annotations) such as
2025-07-12 12:43:17 -04:00
`@pure` to C-imported functions by instead declaring them with the `@C`
attribute:
``` python
@C
@pure
def sqrt(x: float) -> float:
pass
print(sqrt(2.0)) # 1.41421
```
!!! warning
If you're using C++, remember to declare any functions you want to call from
Codon with `extern "C"` to enable C linkage, which Codon expects.
## Type conversions
The following table shows the conversions between Codon and C/C++ types:
| Codon | C/C++ |
| ------------- | ------------------------------------ |
| `int` | `int64_t` |
| `float` | `double` |
| `bool` | `bool` |
| `complex` | `{double, double}` (real and imag.) |
| `str` | `{int64_t, char*}` (length and data) |
| `tuple` | Struct of fields |
| `class` | Pointer to corresponding tuple |
| `Ptr[T]` | `T*` |
!!! warning
Use caution when returning structures from C-imported functions, as C compilers
might use an ABI that differs from Codon's ABI. It is recommended to instead
pass a pointer as an argument that the callee can populate with the return value.
### Optionals
Codon also has an `Optional[T]` type for representing `None` values, which
is represented in one of two ways:
- If `T` is a reference type (i.e. a type defined with `class`), then `Optional[T]`
is represented the same way as `T` (i.e. a pointer to dynamically-allocated member
data) with null representing `None`.
- Otherwise, `Optional[T]` is represented as a C structure `{bool, T}` where the
boolean field indicates whether the value is present.
### NumPy arrays
NumPy array types are parameterized by the data type (`dtype`) and array dimension
(`ndim`). They correspond to the following C structure definition:
``` c
struct ndarray {
int64_t shape[ndim];
int64_t strides[ndim];
dtype *data
};
```
2025-07-13 11:27:01 -04:00
Refer to the [NumPy documentation](../../libraries/numpy.md#array-abi) for an explanation of these fields.
2025-07-12 12:43:17 -04:00
## Dynamic loading
Shared libraries can be loaded dynamically as follows:
``` python
LIBRARY = "libhello.so"
# load dynamically from 'libhello.so'
from C import LIBRARY.foo(int, float) -> None
from C import LIBRARY.bar() -> int as baz
x = foo(1, 2.2)
y = baz()
```
Dynamic C imports are implemented by calling `dlopen()` on the given shared library,
followed by `dlsym()` to obtain the required functions.