Python: C expansion initial experience

Preface

Using Python undoubtedly reduces many rule constraints and development costs, allowing us to focus more on logic than syntax. But gains and losses, development efficiency improved, but has brought operational performance problems, so it is often pursued by other schools of thunder.

As a pythoner, we are also very sad, blame us.

Fortunately, God closed one of our doors, but he opened another window for us, because the bottom layer was written in C, so we could rewrite some of the more performance-hungry features, or modules, in C, and then import XXXXXX seamlessly.Combination.

Even if we have less chance to write C extensions on our own and understand this piece of knowledge, we can get a better understanding of the nature of Python.

Online comparisons are implemented by reference and compilation installations using ctypes or setup. py. Here’s the most primitive way to do this.

Drive fast

1. Implementing interface functions

What does the interface function mean? You can simply understand that achievement is the docking function of Python and C.

Python: CExpand initial experience > ></p>
<p class=We can see that this function is a bit different from the traditional C usage, especially PyObject self, PyObject args, on the side of the function parameter

The first parameter is PyObject *self,This parameter is used internally by Python, and it can be used without management.

The second parameter is PyObject *args,This parameter is very important because it takes all the parameters passed to the function. It is a parameter list that integrates all the parameters.

A string, so if we need to parse these parameters, we need to use a specific pose. We need to use PyArg_ParseTuple to solve this thrilling entrance.

PyArg_ParseTuple Function Description:

1.argsIt is the parameters that need to be transformed.

2.ii That’s the format symbol for the parameter type, which stands for int init; (For more types, see the official website: https://docs.python.org/2/c-a…)

3.The latter, amp; arg1, amp; arg2, is the place where the values extracted by parameter parsing are stored, which is a bit like C’s scanf;

Obviously, there’s a quantitative correlation between these three parameters, that is, if you pass in two int parameters, then you must have two iis, and then you’ll have two actual “containers.” Here’s the catch: if you’re not careful, you’ll have a Segmentation.Fault

For those with parsing parameters, there must be a C module value converted to a Python object, which is Py_BuildValue.

Py_BuildValue Function Description:

Python: CExpand initial experience > ></p>
<p class=1.The first parameter is the same as the second parameters of PyArg_ParseTuple, which are all formatted symbols.

2.The second parameter is the parameter that needs to be transformed, and the function Py_BuildValue assembles all the return fingers into a tuple for Python

Official documents: https://docs.python.org/2/c-api/arg.html

2. Define method list

Python: CExpand initial experience > ></p>
<p class=PyMethodDef Is a C structure used to complete a mapping, that is, easy method lookup, we need to be called outside the method is recorded in this table.

PyMethodDef The members of the structure specify:

1.First field: the method name used in Python;

2.The second field is the function name in the C module.

3.The third field: method parameter type, whether it has no parameter (METH_NOARGS), location parameter (METH_VARARGS), and so on;

4.The fourth field is method description, which can be seen through help () or doc.

It should be noted that the end of the list must be in the form of {NULL, NULL, 0, NULL} to represent the end of the declaration, there are also some big guys with {NULL, NULL}, but I think it will not be exhausting to write complete, on the contrary, it will be more intuitive.

Python: CExpand initial experience > ></p>
<p class=It is because of such a record table that Python can find the corresponding function.

Similarly, if we want to find a C-module method of what the Python function of a module corresponds to, we can get a rough idea of what the Python function corresponds to, such as Python’s list

Python: CExpand initial experience > ></div>
<div class=Python: CExpand initial experience > ></p>
<p class= 3. Initialization function (key)

Python: CExpand initial experience > ></p>
<p class=It’s important to note that this function name can’t be the same as above. It’s prescribed that it must be the init + module name. For example, my last compiled file is test. so, my function name is init test, so in PythonWhen you import the test module, you can find this function and call it.

Here we call the Py_InitModule function to combine the module name and the mapping table. Indicates that the test module uses the mapping table of testMethods.

4. Note object reference management and memory leaks.

Python In object management, memory management, there are reference counting, mark-and-clean, generational recycling and other strategies, where reference counting occurs very often, depending on this usually can solve most of the object residue problems.

So when we write C extensions, we need to keep this in mind.

The following two macros will be used.

1. Additional reference: Py_INCREF example: Py_INCREF (pObj1)

2. Reduce quotes: Py_DECREF example: Py_DECREF (pObj1)

You can’t use free/delete to release directly, you must use Py_DECREF (pObj1), then pObj1 = NULL.

Specific reference:

Official website: https://docs.python.org/2/extending/extending.html#reference-counts

Garbage collection mechanism: http://www.wklken.me/posts/2015/09/29/python-source-gc.html

Compile and export

gcc -I /usr/include/python2.7/ -fpic --shared -o test.so test.c

Complete example

test.c

Python: CExpand initial experience > ></div>
<div class=Python: CExpand initial experience > ></p>
<p class= test.py

import test

print test.test(1, 2) # Output 21

Thanks to the author: Lin_R

Reprinted from https://segmentfault.com/a/1190000015724170

Leave a Reply

Your email address will not be published. Required fields are marked *