# Minimalistic C library and Kotlin/Native

The most trivial Kotlin/Native example of using C library

Some time ago I stuck linking a C binary into an executable with ___isOSVersionAtLeast is undefined. And thus I decided to simplify things to localize the problem. I will write a dedicated post with the solution for ___isOSVersionAtLeast is undefined.

Let’s focus on the most trivial library example. To start with, I assume you have Kotlin/Native compiler in the OS Path. Have a look at the main tutorial or merely download the compiler from GitHub Releases page. Beware, the compiler will download the toolchain on the very first run. The konanc and cinterop tools should be in the PATH of your terminal or console.

The rest of the post is created and tested on macOS. It should just work on Linux, but I did not check it. You shall have C/C++ toolchain installed too. On macOS, it is enough to install and run Xcode.

## C Library

The lib.h file looks as follows

The extern "C" block is not needed (unless you use C++) and left here for C++ compatibility. Thus you may shrink the file to lib.h:

#include guards in your .h files are a standard ritual. They are necessary for multiple .h files projects.

The code above declares one function for export int foo(). We use the .h file later with Kotlin/Native cinterop tool import the function into Kotlin/Native.

Let’s create a lib.c for implementation for the foo function in C:

Now we compile the C sources into a C library. For that we call gcc to compile (and link) the .c sources into a C static library:

It will be a bit more complicated if you have several .c source files.

At that moment we have

• lib.h – the header
• lib.c – the implementation
• lib.o – the intermediate object file
• lib.a – the compiled static library

## Importing to Kotlin/Native

We need to import the C library to be used with Kotlin/Native. It is as tricky as calling a cinterop tool.

The cinterop tool uses the definition file for my library lib.def:

The file helps to specify all necessary options for bigger libraries.

Not it is the time to call the cinterop with the following options:

The result is a lib.klib file. A Kotlin/Native library file. It contains Kotlin APIs for our lib.h. It bridges C types and Kotlin/Native types (trivial Int in our case) and helps to deal with memory management (not needed for our example).

At that moment we have

• lib.h – the header
• lib.c – the implementation
• lib.o – the intermediate object file
• lib.a – the compiled static library
• lib.def – the definitions for cinterop, reference to lib.h
• lib.klib – the compiled Kotlin/Native library to access API from lib.h

## Compiling with Kotlin/Native

We need an entry point and Kotlin sources. I created the main.kt file for that

And I compile it with the following command

and run the ./main.kexe to see the resulting text is being printed:

./main.kexe
The foo() from lib.h returned 42



## Conclusion

That is a trivial C library linking case. For something real, you’ll probably want to use Gradle build.

Take a look at the Interop with C libraries tutorial or the list of Platform libraries.

You may find it useful to check the C Interop docs or Interop with Swift and Objective-C page.