python3调用c语言代码

python 用起来十分方便,但是在执行效率上是硬伤,要是能把一些效率低的循环部分写成C,便可以极大的提升效率。在使用过程中我就遇到了这样的问题,在此做个记录。

python调用C主要有以下方法:

一、CTYPES

将C编译成DLL(WINDOWS)或者SO文件(LINUX)

在PYTHON中用接口调用,该方法使用起来十分简单

假设有add.c的中有一个叫add的函数

1.将该文件编译成SO文件:

#For Linux
$  gcc -shared -Wl,-soname,adder -o adder.so -fPIC add.c
 
#For Mac
$ gcc -shared -Wl,-install_name,adder.so -o adder.so -fPIC add.c

2.调用

from ctypes import *
 
#load the shared object file
adder = CDLL('./adder.so')
 
#Find sum of integers
res_int = adder.add_int(4,5)

ctypes中定义了与C对应的数据类型,详见https://docs.python.org/3.6/library/ctypes.html

二、Python/C API

该方法在初次使用时可能会觉得有点麻烦,但是一旦掌握,PYTHON调用C,将是无往不利!

该方法需要在C中写一个接口运行C代码,然后将结果传给PYTHON。编写该接口主要分为以下四步:

1.写在PYTHON中调用的函数

2.定义该函数

3.创建一个结构体

4.将结构体传给PYTHON

接口完成后只需要创建setup.py将C部分安装成PYTHON可调用的包

具体看代码:

//1.在PYTHON中执行的函数的具体内容,注意函数的命名方式
static PyObject* poptrie_pre2asn(PyObject* self, PyObject* args)
{
    
    char *pre2asnFile;
    char *ipPath;
    char *asPath;

    //PYTHON中读取参数并赋值给C中的变量
    PyArg_ParseTuple( args, "sss", &pre2asnFile, &ipPath, &asPath );
    //调用C中的函数ip2asn
    int res = ip2asn(pre2asnFile,ipPath,asPath);
    //返回结果到PYTHON中
    return Py_BuildValue("i", res);
 

    
}

//说明文档
static char pre2asn_docs[] = "pre2ans(  ): map a prefix to asn\n";

//2.声明该函数,第一个参数是在PYTHON中调用时的函数名,第二个是在C接口中的函数名
static PyMethodDef poptrie_funcs[] =
{
    {"pre2asn", (PyCFunction)poptrie_pre2asn, METH_VARARGS, pre2asn_docs},
    {NULL, NULL, 0, NULL}
};
//3.定义一个结构体,用于将函数具体信息传到PYTHON中,poptrie是python setup后该包的名称
static struct PyModuleDef poptriemodule = {
    PyModuleDef_HEAD_INIT,
    "poptrie",
    "module add yourself",
    -1,
    poptrie_funcs
};

//4.初始化该函数

PyMODINIT_FUNC PyInit_poptrie(void)
{
    return PyModule_Create(&poptriemodule);
}

参数的获取传递等具体方法请参见https://docs.python.org/3/c-api/

函数名的命名请着重注意!

SETUP.PY的编写:

from distutils.core import setup, Extension
 
setup(name='addList', version='1.0',  \
      ext_modules=[Extension('pre2asn', ['main.c'])])

有多个C文件,全写在[]中便可

安装:python setup.py install

大功告成,可以在PYTHON中调用该包了

import poptrie

res = poptrie.pre2asn(,,,)#参数请自行填写

好了,简单记录一下,就写到这了。不当之处敬请批评指正!

你可能感兴趣的:(python学习笔记)