CupinaCoffee
CupinaCoffee

Reputation: 457

External C function compiled using Cython not recognized

I'm trying to learn Cython and have managed to compile .pyx with the function definition straight in the file.

My next step is trying to compile .pyx linking external C functions. The compilation succeeds but when I'm trying to import the module in a Python script the function is not found.

In file "Cython-C.pyx":

cdef extern from "svar.h":
    unsigned long long int svar()

In file "setup.py":

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension(name="Nej", sources=["Cython-C.pyx"])]
setup(
      name = 'blublu',
      cmdclass = {'build_ext': build_ext},
      ext_modules = ext_modules
)

I've tried different sources based on answers around the net such as: sources=["Cython-C.pyx"])], sources=["svar.h","Cython-C.pyx"])], sources=["svar.c","Cython-C.pyx"])] etc..

In file "svar.c":

#include "svar.h"

unsigned long long int svar(){
unsigned long long int i;
unsigned long long int c;
for(i=0; i<100000000; ++i)
{
    c=i/(i+1);
}
return c;
}

In file "svar.h":

unsigned long long int svar();

I compile it on windows using:

python setup.py build_ext --inplace

In file "CWrapperTest.py":

import Nej

print(Nej.svar())

Results in "AttributeError: module 'Nej' has no attribute 'svar'"

And Nej does indeed not contain "svar":

dir(Nej)
Out[2]: 
['__builtins__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 '__test__']

My goal is just trying to get the absolute most basic thing working for learning purposes. I don't think the documentation is clear enough on this issue.

Upvotes: 2

Views: 1293

Answers (1)

DavidW
DavidW

Reputation: 30891

External C functions are only exported as far as Cython - they aren't directly callable from Python. You need to create a Cython wrapper function:

cdef extern from "svar.h":
    unsigned long long int svar()
def svar_py():
    return svar()

You'll be able to call svar_py from Python.

(To my slight surprise this doesn't seem very well documented and perhaps should be).


The correct line in the setup.py file will be

sources=["svar.c","Cython-C.pyx"])]

Upvotes: 3

Related Questions