[//]: # (title: Interoperability with C)

> The C libraries import is in [Beta](native-lib-import-stability.md#stability-of-c-and-objective-c-library-import). All Kotlin declarations
> generated by the cinterop tool from C libraries should have the `@ExperimentalForeignApi` annotation.
>
> Native platform libraries shipped with Kotlin/Native (like Foundation, UIKit, and POSIX)
> require opt-in only for some APIs.
>
{style="note"}

This document covers general aspects of Kotlin's interoperability with C. Kotlin/Native comes with a cinterop tool,
which you can use to quickly generate everything you need to interact with an external C library.

The tool analyzes C headers and produces a straightforward mapping of C types, functions, and strings into Kotlin.
The generated stubs then can be imported into an IDE to enable code completion and navigation.

> Kotlin also provides interoperability with Objective-C. Objective-C libraries are imported through the cinterop tool
> as well. For more details, see [Swift/Objective-C interop](native-objc-interop.md).
>
{style="tip"}

## Setting up your project

Here's a general workflow when working with a project that needs to consume a C library:

1. Create and configure a [definition file](native-definition-file.md). It describes what the cinterop tool should
   include into Kotlin [bindings](#bindings).
2. Configure your Gradle build file to include cinterop in the build process.
3. Compile and run the project to produce the final executable.

> For a hands-on experience, complete the [Create an app using C interop](native-app-with-c-and-libcurl.md) tutorial.
>
{style="note"}

In many cases, there's no need to configure custom interoperability with a C library. Instead, you can use APIs available
on the platform standardized bindings called [platform libraries](native-platform-libs.md). For example,
POSIX on Linux/macOS platforms, Win32 on the Windows platform, or Apple frameworks on macOS/iOS are available this way.

## Bindings

### Basic interop types

All the supported C types have corresponding representations in Kotlin:

* Signed, unsigned integral, and floating point types are mapped to their Kotlin counterpart with the same width.
* Pointers and arrays are mapped to `CPointer<T>?`.
* Enums can be mapped to either Kotlin enum or integral values, depending on heuristics and
  the [definition file settings](native-definition-file.md#configure-enums-generation).
* Structs and unions are mapped to types having fields available via the dot notation, i.e. `someStructInstance.field1`.
* `typedef` are represented as `typealias`.

Also, any C type has the Kotlin type representing the lvalue of this type, i.e., the value located in memory rather than
a simple immutable self-contained value. Think C++ references as a similar concept. For structs (and `typedef`s to
structs), this representation is the main one and has the same name as the struct itself. For Kotlin enums, it's named
`${type}.Var`; for `CPointer<T>`, it's `CPointerVar<T>`; and for most other types, it's `${type}Var`.

For types that have both representations, the one with the lvalue has a mutable `.value` property for accessing the value.

#### Pointer types

The type argument `T` of `CPointer<T>` must be one of the lvalue types described above. For example, the C type
`struct S*` is mapped to `CPointer<S>`, `int8_t*` is mapped to `CPointer<int_8tVar>`, and `char**` is mapped to
`CPointer<CPointerVar<ByteVar>>`.

C null pointer is represented as Kotlin's `null`, and the pointer type `CPointer<T>` is not nullable, but the
`CPointer<T>?` is. The values of this type support all the Kotlin operations related to handling `null`, for example,
`?:`, `?.`, `!!`, and so on:

```kotlin
val path = getenv("PATH")?.toKString() ?: ""
```

Since the arrays are also mapped to `CPointer<T>`, it supports the `[]` operator for accessing values by index:

```kotlin
import kotlinx.cinterop.*

@OptIn(ExperimentalForeignApi::class)
fun shift(ptr: CPointer<ByteVar>, length: Int) {
    for (index in 0 .. length - 2) {
        ptr[index] = ptr[index + 1]
    }
}
```

The `.pointed` property for `CPointer<T>` returns the lvalue of type `T`, pointed by this pointer. The reverse operation
is `.ptr`, it takes the lvalue and returns the pointer to it.

`void*` is mapped to `COpaquePointer` – the special pointer type which is the supertype for any other pointer type.
So if the C function takes `void*`, the Kotlin binding accepts any `CPointer`.

Casting a pointer (including `COpaquePointer`) can be done with `.reinterpret<T>`, for example:

```kotlin
import kotlinx.cinterop.*

@OptIn(ExperimentalForeignApi::class)
val intPtr = bytePtr.reinterpret<IntVar>()
```

Or:

```kotlin
import kotlinx.cinterop.*

@OptIn(ExperimentalForeignApi::class)
val intPtr: CPointer<IntVar> = bytePtr.reinterpret()
```

As is with C, these `.reinterpret` casts are unsafe and can potentially lead to subtle memory problems in the application.

Also, there are unsafe casts between `CPointer<T>?` and `Long` available, provided by the `.toLong()` and `.toCPointer<T>()`
extension methods:

```kotlin
val longValue = ptr.toLong()
val originalPtr = longValue.toCPointer<T>()
```

> If the type of the result is known from the context, you can omit the type argument thanks to the type inference.
> 
{style="tip"}

### Memory allocation

The native memory can be allocated using the `NativePlacement` interface, for example:

```kotlin
@file:OptIn(ExperimentalForeignApi::class)
import kotlinx.cinterop.*

val placement: NativePlacement = // See below for placement examples
val byteVar = placement.alloc<ByteVar>()
val bytePtr = placement.allocArray<ByteVar>(5)
```

The most logical placement is in the object `nativeHeap`. It corresponds to allocating native memory with `malloc` and
provides an additional `.free()` operation to free allocated memory:

```kotlin
@file:OptIn(ExperimentalForeignApi::class)
import kotlinx.cinterop.*

fun main() {
    val size: Long = 0
    val buffer = nativeHeap.allocArray<ByteVar>(size)
    nativeHeap.free(buffer)
}
```

`nativeHeap` requires memory to be freed manually. However, it's often useful to allocate memory with a lifetime bound
to the lexical scope. It's helpful if such memory is freed automatically.

To address this, you can use `memScoped { }`. Inside the braces, the temporary placement is available as an implicit
receiver, so it's possible to allocate native memory with alloc and allocArray, and the allocated memory will be
automatically freed after leaving the scope.

For example, a C function returning values through pointer parameters can be used like:

```kotlin
@file:OptIn(ExperimentalForeignApi::class)
import kotlinx.cinterop.*
import platform.posix.*

val fileSize = memScoped {
    val statBuf = alloc<stat>()
    val error = stat("/", statBuf.ptr)
    statBuf.st_size
}
```

### Pass pointers to bindings

Although C pointers are mapped to the `CPointer<T> type`, C function pointer-typed parameters are mapped to
`CValuesRef<T>.` When passing a `CPointer<T>` as a value of such a parameter, it's passed to the C function as is.
However, a sequence of values can be passed instead of a pointer. In this case, the sequence is passed "by value", i.e.,
the C function receives the pointer to the temporary copy of that sequence, which is valid only until the function returns.

The `CValuesRef<T>` representation of pointer parameters is designed to support C array literals without explicit native
memory allocation. To construct the immutable self-contained sequence of C values, the following methods are provided:

* `${type}Array.toCValues()`, where `type` is the Kotlin primitive type
* `Array<CPointer<T>?>.toCValues()`, `List<CPointer<T>?>.toCValues()`
* `cValuesOf(vararg elements: ${type})`, where `type` is a primitive or pointer

For example:

```c
// C:
void foo(int* elements, int count);
...
int elements[] = {1, 2, 3};
foo(elements, 3);
```

```kotlin
// Kotlin:

foo(cValuesOf(1, 2, 3), 3)
```

### Strings

Unlike other pointers, the parameters of type `const char*` are represented as a Kotlin `String`. So it's possible to
pass any Kotlin string to a binding expecting a C string.

There are also some tools available to convert between Kotlin and C strings manually:

* `fun CPointer<ByteVar>.toKString(): String`
* `val String.cstr: CValuesRef<ByteVar>`.

To get the pointer, `.cstr` should be allocated in native memory, for example:

```kotlin
val cString = kotlinString.cstr.getPointer(nativeHeap)
```

In all cases, the C string is supposed to be encoded as UTF-8.

To skip automatic conversion and ensure raw pointers are used in the bindings, add the
[`noStringConversion` property](native-definition-file.md#set-up-string-conversion) to the `.def` file:

```c
noStringConversion = LoadCursorA LoadCursorW
```

This way, any value of type `CPointer<ByteVar>` can be passed as an argument of `const char*` type. If a Kotlin string
should be passed, code like this could be used:

```kotlin
import kotlinx.cinterop.*

@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
memScoped {
    LoadCursorA(null, "cursor.bmp".cstr.ptr)  // for ASCII or UTF-8 version
    LoadCursorW(null, "cursor.bmp".wcstr.ptr) // for UTF-16 version
}
```

### Scope-local pointers

It's possible to create a scope-stable pointer of C representation for the `CValues<T>` instance using the `CValues<T>.ptr`
extension property, available under `memScoped {}`. It allows using APIs that require C pointers with a lifetime bound
to a certain `MemScope`. For example:

```kotlin
import kotlinx.cinterop.*

@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
memScoped {
    items = arrayOfNulls<CPointer<ITEM>?>(6)
    arrayOf("one", "two").forEachIndexed { index, value -> items[index] = value.cstr.ptr }
    menu = new_menu("Menu".cstr.ptr, items.toCValues().ptr)
    // ...
}
```

In this example, all values passed to the C API `new_menu()` have a lifetime of the innermost `memScope` it belongs to.
Once the control flow leaves the `memScoped` scope, C pointers become invalid.

### Pass and receive structs by value

When a C function takes or returns a struct/union `T` by value, the corresponding argument type or return type is
represented as `CValue<T>`.

`CValue<T>` is an opaque type, so the structure fields cannot be accessed with the appropriate Kotlin properties.
This can be fine if an API uses structures as opaque handles. However, if field access is required, the following
conversion methods are available:

* [`fun T.readValue(): CValue<T>`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/read-value.html)
  converts (the lvalue) `T` to a `CValue<T>`. So to construct the `CValue<T>`,
  `T` can be allocated, filled, and then converted to `CValue<T>`.
* [`CValue<T>.useContents(block: T.() -> R): R`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/use-contents.html)
  temporarily stores the `CValue<T>` in memory, and then runs the passed lambda with this placed value `T` as receiver.
  So to read a single field, you can use the following code:

  ```kotlin
  val fieldValue = structValue.useContents { field }
  ```
  
* [`fun cValue(initialize: T.() -> Unit): CValue<T>`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/c-value.html)
  applies the provided `initialize` function to allocate `T` in memory and converts the result into a `CValue<T>`.
* [`fun CValue<T>.copy(modify: T.() -> Unit): CValue<T>`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/copy.html)
  creates a modified copy of an existing `CValue<T>`. The original value is placed in memory, altered using the `modify()`
  function, and then converted back into a new `CValue<T>`.
* [`fun CValues<T>.placeTo(scope: AutofreeScope): CPointer<T>`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/place-to.html)
  places the `CValues<T>` into an `AutofreeScope`, returning a pointer to the allocated memory. The allocated memory is
  automatically freed when the `AutofreeScope` is disposed.

### Callbacks

To convert a Kotlin function to a pointer to a C function, you can use `staticCFunction(::kotlinFunction)`. It's also
possible to provide a lambda instead of a function reference. The function or lambda must not capture any values.

#### Pass user data to callbacks

Often C APIs allow passing some user data to callbacks. Such data is usually provided by the user when configuring the
callback. It's passed to some C function (or written to the struct) as `void*`, for example. However, references to
Kotlin objects can't be directly passed to C. So they require wrapping before configuring the callback and then unwrapping
in the callback itself, to safely swim from Kotlin to Kotlin through the C world. Such wrapping is possible with
the `StableRef` class.

To wrap the reference:

```kotlin
import kotlinx.cinterop.*

@OptIn(ExperimentalForeignApi::class)
val stableRef = StableRef.create(kotlinReference)
val voidPtr = stableRef.asCPointer()
```

Here, the `voidPtr` is a `COpaquePointer` and can be passed to the C function.

To unwrap the reference:

```kotlin
@OptIn(ExperimentalForeignApi::class)
val stableRef = voidPtr.asStableRef<KotlinClass>()
val kotlinReference = stableRef.get()
```

Here, `kotlinReference` is the original wrapped reference.

The created `StableRef` eventually be manually disposed using the `.dispose()` method to prevent memory leaks:

```kotlin
stableRef.dispose()
```

After that it becomes invalid, so `voidPtr` can't be unwrapped anymore.

### Macros

Every C macro that expands to a constant is represented as a Kotlin property.

Macros without parameters are supported in cases when the compiler can infer the type:

```c
int foo(int);
#define FOO foo(42)
```

In this case, `FOO` is available in Kotlin.

To support other macros, you can expose them manually by wrapping them with supported declarations. For example,
function-like macro `FOO` can be exposed as a function `foo()` by
[adding custom declaration](native-definition-file.md#add-custom-declarations) to the library:

```c
headers = library/base.h

---

static inline int foo(int arg) {
    return FOO(arg);
}
```

### Portability

Sometimes the C libraries have function parameters or struct fields of a platform-dependent type, for example, `long` or
`size_t`. Kotlin itself doesn't provide either implicit integer casts or C-style integer casts (for example,
`(size_t) intValue`), so to make writing portable code in such cases easier, the `convert` method is provided:

```kotlin
fun ${type1}.convert<${type2}>(): ${type2}
```

Here, each of `type1` and `type2` must be an integral type, either signed or unsigned.

`.convert<${type}>` has the same semantics as one of the `.toByte`, `.toShort`, `.toInt`, `.toLong`, `.toUByte`,
`.toUShort`, `.toUInt` or `.toULong` methods, depending on `type`.

An example of using `convert`:

```kotlin
import kotlinx.cinterop.*
import platform.posix.*

@OptIn(ExperimentalForeignApi::class)
fun zeroMemory(buffer: COpaquePointer, size: Int) {
    memset(buffer, 0, size.convert<size_t>())
}
```

Also, the type parameter can be inferred automatically and so may be omitted in some cases.

### Object pinning

Kotlin objects could be pinned, i.e. their position in memory is guaranteed to be stable until they are unpinned,
and pointers to such objects' inner data could be passed to C functions.

There's a couple of approaches you can take:

* Use the [`.usePinned()`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/use-pinned.html) extension function
  that pins an object, executes a block, and unpins it on normal and exception paths:

  ```kotlin
  import kotlinx.cinterop.*
  import platform.posix.*

  @OptIn(ExperimentalForeignApi::class)
  fun readData(fd: Int) {
      val buffer = ByteArray(1024)
      buffer.usePinned { pinned ->
          while (true) {
              val length = recv(fd, pinned.addressOf(0), buffer.size.convert(), 0).toInt()
              if (length <= 0) {
                  break
              }
              // Now `buffer` has raw data obtained from the `recv()` call.
          }
      }
  }
  ```

  Here, `pinned` is an object of a special type `Pinned<T>`. It provides useful extensions like [`.addressOf()`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/address-of.html),
  which allows getting the address of a pinned array body.

* Use the [`.refTo()`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlinx.cinterop/ref-to.html) extension function that has
  similar functionality under the hood but, in certain cases, may help you reduce boilerplate code:

  ```kotlin
  import kotlinx.cinterop.*
  import platform.posix.*
    
  @OptIn(ExperimentalForeignApi::class)
  fun readData(fd: Int) { 
      val buffer = ByteArray(1024)
      while (true) {
          val length = recv(fd, buffer.refTo(0), buffer.size.convert(), 0).toInt()

          if (length <= 0) {
              break
          }
          // Now `buffer` has raw data obtained from the `recv()` call.
      }
  }
  ```

  Here, `buffer.refTo(0)` has the `CValuesRef` type that pins the array before entering the `recv()` function,
  passes the address of its zeroth element to the function, and unpins the array after exiting.

### Forward declarations

To import forward declarations, use the `cnames` package. For example, to import a `cstructName` forward declaration
declared in a C library with a `library.package`, use a special forward declaration package:
`import cnames.structs.cstructName`.

Consider two cinterop libraries: one that has a forward declaration of a struct and another
with an actual implementation in another package:

```C
// First C library
#include <stdio.h>

struct ForwardDeclaredStruct;

void consumeStruct(struct ForwardDeclaredStruct* s) {
    printf("Struct consumed\n");
}
```

```C
// Second C library
// Header:
#include <stdlib.h>

struct ForwardDeclaredStruct {
    int data;
};

// Implementation:
struct ForwardDeclaredStruct* produceStruct() {
    struct ForwardDeclaredStruct* s = malloc(sizeof(struct ForwardDeclaredStruct));
    s->data = 42;
    return s;
}
```

To transfer objects between the two libraries, use an explicit `as` cast in your Kotlin code:

```kotlin
// Kotlin code:
fun test() {
    consumeStruct(produceStruct() as CPointer<cnames.structs.ForwardDeclaredStruct>)
}
```

## What's next

Learn how types, functions, and strings are mapped between Kotlin and C by completing the following tutorials:

* [Mapping primitive data types from C](mapping-primitive-data-types-from-c.md)
* [Mapping struct and union types from C](mapping-struct-union-types-from-c.md)
* [Mapping function pointers from C](mapping-function-pointers-from-c.md)
* [Mapping strings from C](mapping-strings-from-c.md)