Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Hardware and software Environment

  • Ubuntu 18.04 64 – bit
  • Anaconda with python 3.6
  • Cython 0.27.3

Cython profile

Cython is a compiler that allows Python scripts to support EXTENSIONS to the C language. Cython is a superset of Python that converts.pyx scripts encoded in both Python and C into C code. Mainly used to optimize Python script performance or Python calling C function libraries. Due to Python’s inherent poor performance, extending Python with C has become a common way to improve Python performance. This article focuses on using Cython to compile Python code into a dynamically linked library in C, commonly known as SO.

Cython installation

Install first using PIP

pip install cython
Copy the code

Preparing the Python module

Our default library installation directory in Anaconda

CD/home/xugaoxiang anaconda3 / lib/python3.6 / site - packages mkdir djstava CD djstava touch set py test. PyCopy the code

Create files __init__.py and test.py

Edit the contents of the test.py file as

def test():
    '''
    Just an example.
    '''
    print('Hello Cython.')

Copy the code

Next test whether the module created below can be imported and whether the methods in it work properly. This can be done in Python or ipython

Xugaoxiang @ ubuntu: ~ / anaconda3 / lib/python3.6 / site - $python packages/djstava 3.6.4 radar echoes captured | Anaconda custom | (64 - bit) (Default, Jan 16 2018, 18:10:19) [GCC 7.2.0] on Linux Type "help", "copyright", "credits" or "license" for more information. >>> import djstava.test >>> djstava.test.test <function test at 0x7ff35f135598> >>> djstava.test.test() Hello Cython.Copy the code

OK, the test module is now created

Compile into the SO library

Next, use Cython to convert test.py to test.c and compile to the dynamic link library so

CD/home/xugaoxiang anaconda3 / lib/python3.6 / site - packages/djstava cython test. PyCopy the code

Generate the test.c file and use the following command

GCC -fpic - c - I/home/xugaoxiang/anaconda3 / include/python3.6 m test. CCopy the code

Generate the target file that is. O file, and finally link into a dynamic library

gcc -shared test.o -o test.so
Copy the code

At this point, the dynamic library is formally generated.

Test so

Ipython this time we use to test, first advanced to the directory/home/xugaoxiang anaconda3 / lib/python3.6 / site – packages/djstava, will test. Py files deleted, so as not to interfere

Xugaoxiang @ ubuntu: ~ / anaconda3 / lib/python3.6 / site - packages/djstava $ipython Python 3.6.4 radar echoes captured | Anaconda custom | (64 - bit) (default, Jan 16 2018, 18:10:19) Type 'copyright', 'Credits' or 'license' for more information IPython 6.2.1 -- An enhanced Interactive python. Type '? ' for help. In [1]: import djstava.test In [2]: djstava.test.test Out[2]: <cyfunction test at 0x7f90945bbc80> In [3]: djstava.test.test() Hello Cython.Copy the code

The method called to the test module and the result of execution is exactly the same as test.py

In addition, how about in python to call C language dynamic link library, you can refer to previous articles xugaoxiang.com/2019/12/08/…

Used in conjunction with setup.py

If you still don’t understand the setup. Py, please click xugaoxiang.com/2019/12/08/… . In order not to conflict with the above project, we will create a new directory /home/xugaoxiang/test and create a file called test.pyx, which allows C and Python to be mixed

def test():
    '''
    Just an example.
    '''
    print('Hello Cython.')
Copy the code

Write the setup.py file

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name='Test pyx',
    ext_modules=cythonize('test.pyx')
)
Copy the code

After editing, run the python setup.py build command to start the installation

xugaoxiang@ubuntu:~/test$ python setup.py build Compiling test.pyx because it changed. [1/1] Cythonizing test.pyx Build_ext building 'test' extension Creating build/temp. Linux-x86_64-3.6gcc -pthread -B /home/xugaoxiang/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall - Wstrict - as the -fpic - I/home/xugaoxiang/anaconda3 / include/python3.6 m - c test. C - o Linux-x86_64-3.6 /test.o creating build/lib.linux-x86_64-3.6 GCC - pthread-shared-b /home/xugaoxiang/anaconda3/compiler_compat -L/home/xugaoxiang/anaconda3/lib -Wl,-rpath=/home/xugaoxiang/anaconda3/lib - Wl - no - as - men - Wl, -- sysroot = / build/temp. Linux - x86_64-3.6 / test. O - o Build/lib. Linux - x86_64-3.6 / test. The retaining - 36 m - x86_64 - Linux - gnu. SoCopy the code

The compiled file directory structure is as follows

xugaoxiang@ubuntu:~/test$ ls -R .: build setup.py test.c test.pyx ./build: Lib. Linux - x86_64-3.6 temp. Linux - x86_64-3.6 / build/lib. Linux - x86_64-3.6: Test. Retaining - 36 m - x86_64 - Linux - gnu. So. / build/temp. Linux - x86_64-3.6: test. OCopy the code

Notice that the test.c file has been generated, along with the.o and.so files under build. Create a new folder in the current directory, copy the so file from the previous step, and create a new __init__.py file with the contents of

from test import *
Copy the code

And then we start testing

Xugaoxiang @ ubuntu: ~ / test/test $ipython Python 3.6.4 radar echoes captured | Anaconda custom (64 - bit) | (default, Jan 16, 2018, 18:10:19) Type 'copyright', 'Credits' or 'license' for more information IPython 6.2.1 -- An enhanced Interactive python. Type '? ' for help. In [1]: import test In [2]: test.test() Hello Cython.Copy the code

The resources

  • cython.org/
  • Docs.python.org/3/extending…
  • Stackoverflow.com/questions/2…
  • Cython. Readthedocs. IO/en/latest/s…