Python调用C/C++库函数

目录

介绍

使用Python ctypes模块调用C库函数

使用Python扩展机制调用C库


介绍

使用Python很方便,但是在效率上比不上C/C++;再者,某些时候我们想把一些关键性代码保护起来,我们可以将这些代码编译成C/C++的so库,然后使用Python去调用,能够很好的达到我们的目的。

两种方法:

  1. 使用ctypes模块直接加载so
  2. 使用Python扩展

使用Python ctypes模块调用C库函数

C库测试函数

$ ls
Makefile  test_library.c  test_library.h

test_library.c

#include 

int test_function(void)
{
    printf("c library: test_function.\n");
    return 0;
}

test_library.h

int test_function(void);

Makefile

libtest_library.so:
	gcc -fPIC test_library.c -o libtest_library.so -shared
clean:
	rm -rf libtest_library.so test_library.o

执行make编译生成测试C库 libtest_library.so

测试代码test_python.py

from ctypes import *

testlibrary = cdll.LoadLibrary("./libtest_library.so")
testlibrary.test_function()

执行test_python.py测试

$ python3 test_python.py 
c library: test_function.

使用Python扩展机制调用C库

源文件如下:

$ ls
setup.py  test_python_method.c

test_python_method.c

#include 
#include 
#include  

int test_function(void)
{
    printf("c library: test_function.\n");
    return 0;
}

PyObject* wrap_test_function(PyObject* self, PyObject* args)
{
    int ret;
    PyObject* retVal;

    if(!PyArg_ParseTuple(args,""))
        return NULL;
 
    ret = test_function();

    retVal = (PyObject*)Py_BuildValue("i", ret);

    return retVal;
}

static PyMethodDef exampleMethods[] =
{
    {"test_function", wrap_test_function, METH_VARARGS, "An example that python3 call C library functions"},
    {NULL, NULL}
};

#if PY_MAJOR_VERSION >= 3
/* module initialization */
/* Python version 3*/
static struct PyModuleDef test_example_PyDem =
{
    PyModuleDef_HEAD_INIT,
    "test_example",
    "An example",
    -1,
    exampleMethods
};

PyMODINIT_FUNC
PyInit_test_example(void)
{
    return PyModule_Create(&test_example_PyDem);
}

#else

/* module initialization */
/* Python version 2 */
PyMODINIT_FUNC initexample_module(void)
{
    (void) Py_InitModule("test_example", exampleMethods);
}

#endif

setup.py

from distutils.core import setup, Extension

# define the extension module
test_example_module = Extension('test_example', sources=['test_python_method.c'])

# run the setup
setup(ext_modules=[test_example_module])

 使用setup.py生成库文件(中间件)

$ python3 setup.py build_ext --inplace
running build_ext
building 'test_example' extension
creating build
creating build/temp.linux-x86_64-3.8
x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.8 -c test_python_method.c -o build/temp.linux-x86_64-3.8/test_python_method.o
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.8/test_python_method.o -o /home/test/test_example.cpython-38-x86_64-linux-gnu.so
$ ls
build  setup.py  test_example.cpython-38-x86_64-linux-gnu.so test_python_method.c

python调用C库函数测试代码  test_c_method.py

import test_example

test_example.test_function()

测试示例

$ python3 test_c_method.py 
c library: test_function.

 

参考:

2.8. Interfacing with C — Scipy lecture notes

你可能感兴趣的:(Python,C,python)