程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

[Python] simple C extension module

編輯:Python

List of articles

      • describe
      • Environmental Science
      • The design flow of the extension module
        • Header files and C Language program
        • Interface file
        • To write setup.py file
      • test
      • Talk about `python setup.py install`

describe

Use Python An extension of API Write some simple C Extension module , The computing performance and C/C++ Of the same rank .

  • This article aims at a simple C Language extensions to expand

Environmental Science

Test environment :

  • Centos 7.4 x86_64
  • gcc version 4.8.5
  • Python 3.6.8

The design flow of the extension module

  1. Introduce necessary header files : With python.h Several common header files based on
  2. Interface file : be responsible for C Language and Python Language interaction between
  3. To write setup.py: Script for configuring extension module meta information

Header files and C Language program

The header file name is sample.h, The details are as follows

/* sample.h */
#include <math.h>
extern int gcd(int, int);
extern int in_mandel(double x0, double y0, int n);
extern int divide(int a, int b, int *remainder);
extern double avg(double *a, int n);
typedef struct Point {

double x,y;
} Point;
extern double distance(Point *p1, Point *p2);

C Language program sample.c, It reads as follows

/* sample.c */
#include <math.h>
/* Compute the greatest common divisor */
int gcd(int x, int y) {

int g = y;
while (x > 0) {

g = x;
x = y % x;
y = g;
}
return g;
}
/* Test if (x0,y0) is in the Mandelbrot set or not */
int in_mandel(double x0, double y0, int n) {

double x=0,y=0,xtemp;
while (n > 0) {

xtemp = x*x - y*y + x0;
y = 2*x*y + y0;
x = xtemp;
n -= 1;
if (x*x + y*y > 4) return 0;
}
return 1;
}
/* Divide two numbers */
int divide(int a, int b, int *remainder) {

int quot = a / b;
*remainder = a % b;
return quot;
}

Put the standard C Files are compiled into standard dynamic libraries , namely libsamplpe.so

gcc -shared -fPIC sample.c -o libsample.so
# This operation makes no sense , Just to prove C The language file is correct 

Interface file

pysample.c Be responsible for C Language and Python Language interaction between , Code responsible for numerical conversion in two environments .
In a way pysample.c More like an interface , Just like header files for standards C file .
pysample.c The contents of the document are as follows :

#include "Python.h"
#include "sample.h"
/* int gcd(int, int) */
static PyObject *py_gcd(PyObject *self, PyObject *args) {

int x, y, result;
if (!PyArg_ParseTuple(args,"ii", &x, &y)) {

return NULL;
}
result = gcd(x,y);
return Py_BuildValue("i", result);
}
/* int in_mandel(double, double, int) */
static PyObject *py_in_mandel(PyObject *self, PyObject *args) {

double x0, y0;
int n;
int result;
if (!PyArg_ParseTuple(args, "ddi", &x0, &y0, &n)) {

return NULL;
}
result = in_mandel(x0,y0,n);
return Py_BuildValue("i", result);
}
/* int divide(int, int, int *) */
static PyObject *py_divide(PyObject *self, PyObject *args) {

int a, b, quotient, remainder;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {

return NULL;
}
quotient = divide(a,b, &remainder);
return Py_BuildValue("(ii)", quotient, remainder);
}
/* Module method table */
static PyMethodDef SampleMethods[] = {

{
"gcd", py_gcd, METH_VARARGS, "Greatest common divisor"},
{
"in_mandel", py_in_mandel, METH_VARARGS, "Mandelbrot test"},
{
"divide", py_divide, METH_VARARGS, "Integer division"},
{
 NULL, NULL, 0, NULL}
};
/* Module structure */
static struct PyModuleDef samplemodule = {

PyModuleDef_HEAD_INIT,
"sample", /* name of module */
"A sample module", /* Doc string (may be NULL) */
-1, /* Size of per-interpreter state or -1 */
SampleMethods /* Method table */
};
/* Module initialization function */
PyMODINIT_FUNC
PyInit_sample(void) {

return PyModule_Create(&samplemodule);
}

To write setup.py file

setup.py The contents of the document are as follows

# setup.py
from distutils.core import setup, Extension
setup(name='sample',
ext_modules=[
Extension('sample',
['sample.c', 'pysample.c'],
include_dirs = ['sample'],
)
]
)

Finish editing setup.py After the document , Enter the command

python3 setup.py build_ext --inplace

View the compiled results

After compiling, it will generate sample.cpython-36m-x86_64-linux-gnu.so Dynamic link library , That is, the extension module

test

Edit test file example.py, The contents are as follows

import sample
print(sample.gcd(35,42))
print(sample.in_mandel(0,0,500))
print(sample.in_mandel(2.0,1.0,500))
print(sample.divide(42,8))

function

python3 example.py

Running results

[[email protected] m2]# python3 example.py
7
1
0
(5, 2)

Talk about python setup.py install

python setup.py install There are two steps :

python setup.py build
python setup.py install

These two steps can be performed separately , You can also just execute python setup.py install, because python setup.py install Always first build after install.

python setup.py build yes python compile module The process of , Finally, it will generate build Folder .build After that install The process is copying build/lib File to user specified lib library .

reference :

  • https://www.cnblogs.com/devilmaycry812839668/p/8446910.html
  • https://python3-cookbook.readthedocs.io/zh_CN/latest/c15/p02_write_simple_c_extension_module.html#id1

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved