Far from a c expert but for me using ubuntu, the following works:

main.c:

#include "foo_api.h"
#include <stdio.h>


int main(int argc, char *argv[]) {
     Py_Initialize();
     initfoo();
     import_foo();
     double arr[5] = {1,2,3,4,5};
     int i = 0;
     foo(arr);
     for(i = 0; i < 5; i++)
    {
      printf("%f\n", arr[i]);
    }
     Py_Finalize();
     return 0;
}

foo.pyx:

cdef public api  foo(double* x):
   x[0] = 0.0

From the same directory:

$ cython foo.pyx 

Then:

$ cc -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7   -o foo  *.c -lpython2.7 

Then just run.

$ ./foo
0.000000
2.000000
3.000000
4.000000
5.000000

I used pkg-config --cflags python to get the flags:

 $ pkg-config --cflags python
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 

Without calling Py_Initialize (Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions;), you will get:

Fatal Python error: PyThreadState_Get: no current thread
Aborted (core dumped)

Without initfoo() or import_foo() you get a:

 Segmentation fault (core dumped)

If you don't call Py_Finalize:

Py_Initialize a no-op when called for a second time (without calling Py_Finalize() first).

To get the delorean example from the docs to run:

main.py:

#include "delorean_api.h"
#include <stdio.h>
Vehicle car;


int main(int argc, char *argv[]) {
     Py_Initialize();
     initdelorean();
     import_delorean();
     car.speed = atoi(argv[1]);
     car.power = atof(argv[2]);
     activate(&car);
     Py_Finalize();
     return 0;
}

delorean.pyx:

ctypedef public struct Vehicle:
    int speed
    float power

cdef api void activate(Vehicle *v):
    if v.speed >= 88 and v.power >= 1.21:
        print "Time travel achieved"
    else:
        print("Sorry Marty")

The procedure is the same, the only change was I had to use ctypedef with the Vehicle struct or else in main or use I had t use struct Vehicle car; in main:

$ cython delorean.pyx
$ cc  -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7   -o delorean  *.c -lpython2.7  
$ ./delorean 1 1
Sorry Marty
$ ./delorean 100 2
Time travel achieved

You can also get it to work without using Py_Initialize etc...

In foo.pyx you just need to make the function public:

cdef public  foo(double* x):
   x[0] = 0.0

I added #include <python2.7/Python.h> just imported foo.hin main.c and removed Py_Initialize(); etc. Just importing python.h would not work for me but that may not be the case for everyone.

#include <python2.7/Python.h>
#include "foo.h"
#include <stdio.h>


int main(int argc, char *argv[]) {
     double arr[5] = {1,2,3,4,5};
     int i = 0;
     foo(arr);
     for(i = 0; i < 5; i++)
    {
      printf("%f\n", arr[i]);
    }

     return 0;
}

Compiling was the same:

$ cython foo.pyx 
$ cc -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7   -o foo  *.c -lpython2.7 
$ ./foo
0.000000
2.000000
3.000000
4.000000
5.000000

If you are using the api version then just include the api header or vice versa as per the docs However, note that you should include either modulename.h or modulename_api.h in a given C file, not both, otherwise you may get conflicting dual definitions.

To do the same with the delorean example I had to use libc.stdio to print the strings to avoid a segmentation fault:

from libc.stdio cimport printf

ctypedef public  struct Vehicle:
    int speed
    float power

cdef public void activate(Vehicle *v):
    if v.speed >= 88 and v.power >= 1.21:
        printf("Time travel achieved\n")
    else:
        printf("Sorry Marty\n")

main:

#include <python2.7/Python.h>
#include <stdio.h>
#include "delorean.h"

Vehicle car;


int main(int argc, char *argv[]) {
     car.speed = atoi(argv[1]);
     car.power = atof(argv[2]);
     activate(&car);
     return 0;
}

It might make more sense to return the values:

ctypedef public  struct Vehicle:
    int speed
    float power

cdef public  char* activate(Vehicle *v):
    if v.speed >= 88 and v.power >= 1.21:
        return  "Time travel achieved"
    return "Sorry Marty"

main:

#include <python2.7/Python.h>
#include <stdio.h>
#include "delorean.h"

Vehicle car;

int main(int argc, char *argv[]) {
     car.speed = atoi(argv[1]);
     car.power = atof(argv[2]);
     printf("%s\n",activate(&car));
     return 0;
}
Answer from Padraic Cunningham on Stack Overflow
๐ŸŒ
Machine Learning Plus
machinelearningplus.com โ€บ blog โ€บ how to convert python code to cython (and speed up 100x)?
How to convert Python code to Cython (and speed up 100x)? | machinelearningplus
October 17, 2023 - Using Cython, you can speed up existing Python code by an order of 100x or more. This is possible because Cython converts some of the Python code to C by doing some basic code changes.
๐ŸŒ
GitHub
github.com โ€บ cython โ€บ cython
GitHub - cython/cython: The most widely used Python to C compiler ยท GitHub
C compile time adaptation to the target platform and Python version ยท support for other C-API implementations, including PyPy and Pyston ... Cython was originally based on Pyrex by Greg Ewing, with the following written in the Pyrex readme document:
Author: cython
Top answer
1 of 1
15

Far from a c expert but for me using ubuntu, the following works:

main.c:

#include "foo_api.h"
#include <stdio.h>


int main(int argc, char *argv[]) {
     Py_Initialize();
     initfoo();
     import_foo();
     double arr[5] = {1,2,3,4,5};
     int i = 0;
     foo(arr);
     for(i = 0; i < 5; i++)
    {
      printf("%f\n", arr[i]);
    }
     Py_Finalize();
     return 0;
}

foo.pyx:

cdef public api  foo(double* x):
   x[0] = 0.0

From the same directory:

$ cython foo.pyx 

Then:

$ cc -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7   -o foo  *.c -lpython2.7 

Then just run.

$ ./foo
0.000000
2.000000
3.000000
4.000000
5.000000

I used pkg-config --cflags python to get the flags:

 $ pkg-config --cflags python
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 

Without calling Py_Initialize (Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions;), you will get:

Fatal Python error: PyThreadState_Get: no current thread
Aborted (core dumped)

Without initfoo() or import_foo() you get a:

 Segmentation fault (core dumped)

If you don't call Py_Finalize:

Py_Initialize a no-op when called for a second time (without calling Py_Finalize() first).

To get the delorean example from the docs to run:

main.py:

#include "delorean_api.h"
#include <stdio.h>
Vehicle car;


int main(int argc, char *argv[]) {
     Py_Initialize();
     initdelorean();
     import_delorean();
     car.speed = atoi(argv[1]);
     car.power = atof(argv[2]);
     activate(&car);
     Py_Finalize();
     return 0;
}

delorean.pyx:

ctypedef public struct Vehicle:
    int speed
    float power

cdef api void activate(Vehicle *v):
    if v.speed >= 88 and v.power >= 1.21:
        print "Time travel achieved"
    else:
        print("Sorry Marty")

The procedure is the same, the only change was I had to use ctypedef with the Vehicle struct or else in main or use I had t use struct Vehicle car; in main:

$ cython delorean.pyx
$ cc  -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7   -o delorean  *.c -lpython2.7  
$ ./delorean 1 1
Sorry Marty
$ ./delorean 100 2
Time travel achieved

You can also get it to work without using Py_Initialize etc...

In foo.pyx you just need to make the function public:

cdef public  foo(double* x):
   x[0] = 0.0

I added #include <python2.7/Python.h> just imported foo.hin main.c and removed Py_Initialize(); etc. Just importing python.h would not work for me but that may not be the case for everyone.

#include <python2.7/Python.h>
#include "foo.h"
#include <stdio.h>


int main(int argc, char *argv[]) {
     double arr[5] = {1,2,3,4,5};
     int i = 0;
     foo(arr);
     for(i = 0; i < 5; i++)
    {
      printf("%f\n", arr[i]);
    }

     return 0;
}

Compiling was the same:

$ cython foo.pyx 
$ cc -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7   -o foo  *.c -lpython2.7 
$ ./foo
0.000000
2.000000
3.000000
4.000000
5.000000

If you are using the api version then just include the api header or vice versa as per the docs However, note that you should include either modulename.h or modulename_api.h in a given C file, not both, otherwise you may get conflicting dual definitions.

To do the same with the delorean example I had to use libc.stdio to print the strings to avoid a segmentation fault:

from libc.stdio cimport printf

ctypedef public  struct Vehicle:
    int speed
    float power

cdef public void activate(Vehicle *v):
    if v.speed >= 88 and v.power >= 1.21:
        printf("Time travel achieved\n")
    else:
        printf("Sorry Marty\n")

main:

#include <python2.7/Python.h>
#include <stdio.h>
#include "delorean.h"

Vehicle car;


int main(int argc, char *argv[]) {
     car.speed = atoi(argv[1]);
     car.power = atof(argv[2]);
     activate(&car);
     return 0;
}

It might make more sense to return the values:

ctypedef public  struct Vehicle:
    int speed
    float power

cdef public  char* activate(Vehicle *v):
    if v.speed >= 88 and v.power >= 1.21:
        return  "Time travel achieved"
    return "Sorry Marty"

main:

#include <python2.7/Python.h>
#include <stdio.h>
#include "delorean.h"

Vehicle car;

int main(int argc, char *argv[]) {
     car.speed = atoi(argv[1]);
     car.power = atof(argv[2]);
     printf("%s\n",activate(&car));
     return 0;
}
๐ŸŒ
GitHub
gist.github.com โ€บ vi4hu โ€บ a1aae1a6d209705a14bca2b7c4c7625e
Convert and Compile python in c via cython ยท GitHub
Convert and Compile python in c via cython. GitHub Gist: instantly share code, notes, and snippets.
๐ŸŒ
Cython
cython.readthedocs.io โ€บ en โ€บ latest โ€บ src โ€บ tutorial โ€บ cython_tutorial.html
Basic Tutorial โ€” Cython 3.3.0 documentation
The fundamental nature of Cython can be summed up as follows: Cython is Python with C data types. Cython is Python: Almost any piece of Python code is also valid Cython code. (There are a few Limitations, but this approximation will serve for now.) The Cython compiler will convert it into C code ...
๐ŸŒ
Opensource.com
opensource.com โ€บ article โ€บ 21 โ€บ 4 โ€บ cython
Optimize your Python code with C | Opensource.com
April 26, 2021 - CC BY-SA 4.0 ยท Cython is a compiler ... is also a superset of the Python language, and it supports calling C functions and declaring C types on variables and class attributes....
๐ŸŒ
Academify
academify.com.br โ€บ home โ€บ blog โ€บ fundamentals โ€บ convert python to c code with cython
Convert Python to C Code with Cython
May 19, 2026 - Use the cython -a command: This generates an HTML annotation file showing which lines of your code still depend on the Python interpreter (highlighted in yellow). The goal is to make critical lines as white as possible. Disable safety checks where safe: If you are certain your list indexes are always within bounds, use the @cython.boundscheck(False) decorator to skip bounds verification and gain additional speed. Profile first: Only convert the slowest functions.
Find elsewhere
๐ŸŒ
Machine Learning Plus
machinelearningplus.com โ€บ blog โ€บ how to convert python to cython inside jupyter notebooks?
How to convert Python to Cython inside Jupyter Notebooks? - machinelearningplus
October 6, 2023 - Interesting isnโ€™t it? However, unlike CPython, the Cython module converts code back into C, compiles it and we can directly call the compiled function without the need for an interpreter.
๐ŸŒ
YouTube
youtube.com โ€บ watch
Cython 3.0: Compiling Python to C, the next generation - YouTube
The Cython project compiles Python to C -- not just to make code faster, but also to wrap external C libraries easily, and make it easy to write C extensions...
Published: July 25, 2023
๐ŸŒ
Quora
quora.com โ€บ I-want-to-convert-my-Python-code-to-C-with-Cython-and-then-compile-it-to-exe-for-Windows-64-bit-How-can-I-do-that
I want to convert my Python code to C with Cython and then compile it to .exe for Windows 64 bit. How can I do that? - Quora
Answer: You can follow the below steps - 1. As Cython can accept only valid python source file so first make sure that your python code is working without any error/issue. 2. Give a file name extension as .pyx instead of .py extension. 3. Then you can write a Setup.py file for Cython. A basic cy...
๐ŸŒ
GitHub
hplgit.github.io โ€บ primer.html โ€บ doc โ€บ pub โ€บ cython โ€บ cython-readable.html
Migrating Python to compiled code
August 13, 2020 - Hans Petter Langtangen [1, 2] ยท Pure Python code for Monte Carlo simulation The computational problem A scalar Python implementation A vectorized Python implementation Migrating scalar Python code to Cython A plain Cython implementation A better Cython implementation Migrating code to C Writing ...
๐ŸŒ
Arch Linux Forums
bbs.archlinux.org โ€บ viewtopic.php
Converting Python To C with Cython / Programming & Scripting / Arch Linux Forums
Fix the Include in your Cython converted C-File, like this: #include "python2.7/Python.h" instead of #include "Python.h".
๐ŸŒ
Ron
ron.sh โ€บ compiling-python-code-with-cython
Compiling Python Code with Cython
April 11, 2021 - If you have been developing using ... programming language and the Cython programming language, which is a superset of Python. What Cython does is convert your Python code to C and then build/compile it using a C compiler of your choice....
๐ŸŒ
Towards Data Science
towardsdatascience.com โ€บ home โ€บ latest โ€บ cython for absolute beginners: 30x faster code in two simple steps
Cython for absolute beginners: 30x faster code in two simple steps | Towards Data Science
March 5, 2025 - Combine the ease and speed of ... We do this by using a package called Cython that will convert our Python-code to a compiled, superfast piece of C-code that we can directly import into our project again....
๐ŸŒ
FutureLearn
futurelearn.com โ€บ home โ€บ blog
Interfacing C code with Cython
October 25, 2022 - In this article we discuss how external code written in C can be utilized from Python code with the help of Cython. As Cython code compiles down to C code, it is relatively straightforward to utilize also Cython for interfacing with C.
๐ŸŒ
Medium
medium.com โ€บ @v1per โ€บ cython-use-c-c-functions-in-python-fcb91dae8533
Cython โ€” use C/C++ functions in Python | by Himanshu Das | Medium
September 17, 2023 - Cython is based on Pyrex, but supports more cutting edge functionality and optimizations. Cython translates Python code to C/C++ code, but additionally supports calling C functions and declaring C types on variables and class attributes.
๐ŸŒ
Santhalakshminarayana
santhalakshminarayana.github.io โ€บ blog โ€บ super-fast-python-cython
Super fast Python (Part-4): Cython- Santha Lakshmi Narayana
November 18, 2022 - One thing we can do is to convert the Python code into a low-level programming language like C/C++ and embed that C/C++ code in Python. Understanding and writing C/C++ code is hard for someone who is not familiar with C/C++. Fortunately, we can get the performance speed as fast as C/C++ by writing the Python code in Cython which is a superset of Python that provides functionality to write C-Extensions for Python.