目录
介绍
使用Python ctypes模块调用C库函数
使用Python扩展机制调用C库
介绍
使用Python很方便,但是在效率上比不上C/C++;再者,某些时候我们想把一些关键性代码保护起来,我们可以将这些代码编译成C/C++的so库,然后使用Python去调用,能够很好的达到我们的目的。
两种方法:
- 使用ctypes模块直接加载so
- 使用Python扩展
使用Python ctypes模块调用C库函数
C库测试函数
$ ls Makefile test_library.c test_library.h
test_library.c
#includeint 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 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 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



