'I don't know how to wrap the .c file and.pyx file code

I am beginner in Cython and I am learning it from a book of O’Reilly's Cython and I have an issue in the code that I do not know that how I can wrap the code of .c file (C file) and .pyx file(Cython file) for making usable in python

the (wrap_fib.py file ) code is here:-

from distutils.core import setup,Extension
from Cython.Build import cythonize
ext=Extension(name='wrap_fib',sources=['wrap_fib_c.c','wrap_fib_cython.pyx'])
setup(ext_modules=cythonize(ext))

the (wrap_fib_c.c file) code is here:-

double cfib(int n);

the (wrap_fib_cython.pyx file) code is here:-

cdef extern from "cfib.h":
double cfib(int n)
def fib(n):
return cfib(n)

if you want the code of 'fib.pyx' file so it is here:-

def fib(int n):
    cdef int i 
    cdef double a=0.0,b=1.0
    for i in range(n):
        a,b=a+b,a
    return a

i can't understand that from which of the command I will wrapped the code and make it useable. if I use the command python wrap_fib.py build_ext --inplace, so it will show the error such as:

wrap_fib_cython.c(699): fatal error C1083: Cannot open include file: 'cfib.h': No such file or directory
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.29.30133\\bin\\HostX86\\x64\\cl.exe' failed with exit code 2

so can you please tell me that how i can solve this and what will I do for wrapped the code for python file. if you solve this I really appericate your efforts!! Thank You.



Solution 1:[1]

As the error message says, the problem is that you don't have a C header file. I'll leave a simple example for you to understand how it works.

Suppose that you have some random C function you want to use in a python program:

c_code.c

double add_c(double a, double b){
    return a + b;
}

To be able to use that function in other programs, you declare it inside a header file:

c_code.h

double add_c(double a, double b);

Then you need to write your cython code and import the function:

cython_code.pyx

# cython: language_level = 3

cdef extern from "c_code.h":

    cdef double add_c(double a, double b)

def add_cy(double a, double b):

    print(f"{a} + {b} = {add_c(a, b)}")

Now, you just need to write the setup script, compile the code, and the add_c function will be available for you to use in a python program.

setup.py

from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize


ext_modules = [
    Extension(
        name="cython_code",
        sources=[
            "cython_code.pyx",
            "c_code.c"
        ]
    )
]

if __name__ == "__main__":

    setup(
        ext_modules=cythonize(ext_modules)
    )

foo.py

from c_code import add_cy

add_cy(1., 3.)

Using definition files

As you are reading the O'Reilly book, you will or may already have learned about the .pxd files, which are particularly suitable for this purpose. The implementation would look like this.

cython_code.pxd

cdef extern from "c_code.h":

    cdef double add_c(double a, double b)

cython_code.pyx

# cython: language_level = 3

def add_cy(double a, double b):

    print(f"{a} + {b} = {add_c(a, b)}")

As both the .pyx and the .pxd files have the same name, you don't even need to import the function, but the code would still work if you decide to add that extra line.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1