Commit 6e4779ce authored by scoder's avatar scoder Committed by GitHub

Merge pull request #2326 from gabrieldemarmiesse/test_calling_c_functions

Adding tests for the code snippets in "Calling C functions".
parents 60e6c1fd e9fdcd7f
from libc.stdlib cimport atoi
cdef parse_charptr_to_py_int(char*s):
assert s is not NULL, "byte string value is NULL"
return atoi(s) # note: atoi() has no error detection!
"""
>>> sin(0)
0.0
"""
cdef extern from "math.h":
cpdef double sin(double x)
cdef extern from "string.h":
char* strstr(const char *haystack, const char *needle)
cdef extern from "string.h":
char* strstr(const char *haystack, const char *needle)
cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
cdef char* pos = strstr(needle='akd', haystack=data)
print(pos != NULL)
from libc.math cimport sin
cdef double f(double x):
return sin(x * x)
from cpython.version cimport PY_VERSION_HEX
# Python version >= 3.2 final ?
print(PY_VERSION_HEX >= 0x030200F0)
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules = [
Extension("demo",
sources=["demo.pyx"],
libraries=["m"] # Unix-like specific
)
]
setup(name="Demos",
ext_modules=cythonize(ext_modules))
......@@ -13,13 +13,9 @@ functions for you. So you can just cimport and use them.
For example, let's say you need a low-level way to parse a number from
a ``char*`` value. You could use the ``atoi()`` function, as defined
by the ``stdlib.h`` header file. This can be done as follows::
by the ``stdlib.h`` header file. This can be done as follows:
from libc.stdlib cimport atoi
cdef parse_charptr_to_py_int(char* s):
assert s is not NULL, "byte string value is NULL"
return atoi(s) # note: atoi() has no error detection!
.. literalinclude:: ../../examples/tutorial/external/atoi.pyx
You can find a complete list of these standard cimport files in
Cython's source package
......@@ -30,19 +26,13 @@ Cython declarations that can be shared across modules
Cython also has a complete set of declarations for CPython's C-API.
For example, to test at C compilation time which CPython version
your code is being compiled with, you can do this::
from cpython.version cimport PY_VERSION_HEX
# Python version >= 3.2 final ?
print PY_VERSION_HEX >= 0x030200F0
your code is being compiled with, you can do this:
Cython also provides declarations for the C math library::
.. literalinclude:: ../../examples/tutorial/external/py_version_hex.pyx
from libc.math cimport sin
Cython also provides declarations for the C math library:
cdef double f(double x):
return sin(x*x)
.. literalinclude:: ../../examples/tutorial/external/libc_sin.pyx
Dynamic linking
......@@ -52,24 +42,9 @@ The libc math library is special in that it is not linked by default
on some Unix-like systems, such as Linux. In addition to cimporting the
declarations, you must configure your build system to link against the
shared library ``m``. For distutils, it is enough to add it to the
``libraries`` parameter of the ``Extension()`` setup::
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules=[
Extension("demo",
sources=["demo.pyx"],
libraries=["m"] # Unix-like specific
)
]
setup(
name = "Demos",
ext_modules = cythonize(ext_modules)
)
``libraries`` parameter of the ``Extension()`` setup:
.. literalinclude:: ../../examples/tutorial/external/setup.py
External declarations
---------------------
......@@ -95,15 +70,9 @@ library.
Note that you can easily export an external C function from your Cython
module by declaring it as ``cpdef``. This generates a Python wrapper
for it and adds it to the module dict. Here is a Cython module that
provides direct access to the C ``sin()`` function for Python code::
"""
>>> sin(0)
0.0
"""
provides direct access to the C ``sin()`` function for Python code:
cdef extern from "math.h":
cpdef double sin(double x)
.. literalinclude:: ../../examples/tutorial/external/cpdef_sin.pyx
You get the same result when this declaration appears in the ``.pxd``
file that belongs to the Cython module (i.e. that has the same name,
......@@ -124,19 +93,15 @@ names like this::
However, this prevents Cython code from calling it with keyword
arguments (supported since Cython 0.19). It is therefore preferable
to write the declaration like this instead::
to write the declaration like this instead:
cdef extern from "string.h":
char* strstr(const char *haystack, const char *needle)
.. literalinclude:: ../../examples/tutorial/external/keyword_args.pyx
You can now make it clear which of the two arguments does what in
your call, thus avoiding any ambiguities and often making your code
more readable::
cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh"
more readable:
pos = strstr(needle='akd', haystack=data)
print pos != NULL
.. literalinclude:: ../../examples/tutorial/external/keyword_args_call.pyx
Note that changing existing parameter names later is a backwards
incompatible API modification, just as for Python code. Thus, if
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment