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