我正在尝试在Python中实现C扩展。扩展程序有效,但只要导入模块,errno
就会设置为ENOENT
(2)。
simple.c
#include <Python.h>
#include <errno.h>
static PyMethodDef KeypadMethods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyMODINIT_FUNC initkeypadinterface(void)
{
PyObject* m;
int stat;
stat = errno;
if (stat)
{
printf("There was an error: %d\n", stat);
}
m = Py_InitModule3("keypadinterface", KeypadMethods, "Interface to the keypad driver");
if (m == NULL)
{
return;
}
}
setup.py
from distutils.core import setup, Extension
module1 = Extension('keypadinterface',
sources = ['simple.c'])
setup (name = 'KeypadInterface',
version = '0.1',
description = 'Provides a python interface to the keypad driver',
ext_modules = [module1])
python setup.py build
输出:
running build
running build_ext
building 'keypadinterface' extension
creating build
creating build/temp.linux-x86_64-2.7
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c simple.c -o build/temp.linux-x86_64-2.7/simple.o
creating build/lib.linux-x86_64-2.7
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/simple.o -o build/lib.linux-x86_64-2.7/keypadinterface.so
在errno上使用带有监视的gdb会导致此回溯:
(gdb) c
Continuing.
Hardware watchpoint 1: errno
Old value = 0
New value = 2
0x00007f9974e271d0 in __xstat64 () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007f9974e271d0 in __xstat64 () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00000000004d4ea6 in stat (__path=<optimized out>, __statbuf=<optimized out>)
at /usr/include/x86_64-linux-gnu/sys/stat.h:455
#2 isdir (path=0x14bf430 "keypadinterface") at ../Python/import.c:133
#3 find_module.38998 (fullname=fullname@entry=0x14be420 "keypadinterface", subname=<optimized out>,
subname@entry=0x14be420 "keypadinterface",
path=['', '/usr/local/lib/python2.7/dist-packages/esptool-0.1.0-py2.7.egg', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client'], path@entry=0x0, buf=<optimized out>, buf@entry=0x14bf430 "keypadinterface",
buflen=buflen@entry=4097, p_fp=p_fp@entry=0x7fff1d45bb80, p_loader=p_loader@entry=0x7fff1d45bb70)
at ../Python/import.c:1497
#4 0x0000000000540922 in import_submodule.39248 (mod=mod@entry=None,
subname=subname@entry=0x14be420 "keypadinterface", fullname=0x14be420 "keypadinterface")
at ../Python/import.c:2689
#5 0x0000000000540d08 in load_next (mod=None, altmod=None, p_name=p_name@entry=0x7fff1d45bc78,
buf=buf@entry=0x14be420 "keypadinterface", p_buflen=p_buflen@entry=0x7fff1d45bc80)
at ../Python/import.c:2515
#6 0x000000000054111b in import_module_level.isra.3.39267 (name=0x0,
name@entry=0x7f99753d4d74 "keypadinterface",
globals=globals@entry={'__builtins__': <module at remote 0x7f99754dbb08>, '__name__': '__main__', '__doc__': None, '__package__': None}, fromlist=fromlist@entry=None, level=level@entry=-1) at ../Python/import.c:2224
#7 0x000000000051dc50 in PyImport_ImportModuleLevel (level=-1, fromlist=None, locals=<optimized out>,
globals={'__builtins__': <module at remote 0x7f99754dbb08>, '__name__': '__main__', '__doc__': None, '__package__': None}, name=0x7f99753d4d74 "keypadinterface") at ../Python/import.c:2288
#8 builtin___import__ (self=<optimized out>, args=<optimized out>, kwds=<optimized out>)
at ../Python/bltinmodule.c:49
#9 0x00000000004dc9cb in PyObject_Call (kw=0x0,
arg=('keypadinterface', {'__builtins__': <module at remote 0x7f99754dbb08>, '__name__': '__main__', '__doc__': None, '__package__': None}, {...}, None), func=<built-in function __import__>)
at ../Objects/abstract.c:2529
#10 PyEval_CallObjectWithKeywords (func=func@entry=<built-in function __import__>,
arg=arg@entry=('keypadinterface', {'__builtins__': <module at remote 0x7f99754dbb08>, '__name__': '__main__', '__doc__': None, '__package__': None}, {...}, None), kw=kw@entry=0x0) at ../Python/ceval.c:3889
#11 0x000000000049b87e in PyEval_EvalFrameEx (
f=f@entry=Frame 0x7f9975504c20, for file <stdin>, line 1, in <module> (), throwflag=throwflag@entry=0)
at ../Python/ceval.c:2333
#12 0x00000000004a1634 in PyEval_EvalCodeEx (closure=0x0, defcount=0, defs=0x0, kwcount=0, kws=0x0,
argcount=0, args=0x0, locals=<optimized out>, globals=<optimized out>, co=0x7f9975415b30)
at ../Python/ceval.c:3252
#13 PyEval_EvalCode (locals=<optimized out>, globals=<optimized out>, co=0x7f9975415b30)
at ../Python/ceval.c:667
#14 run_mod.42576 (mod=mod@entry=0x14bc470, filename=filename@entry=0x60e5bd "<stdin>",
globals=<optimized out>, locals=<optimized out>, flags=flags@entry=0x7fff1d45c0b0,
arena=arena@entry=0x1444780) at ../Python/pythonrun.c:1370
#15 0x000000000044e87c in PyRun_InteractiveOneFlags (fp=fp@entry=0x7f99750fb640 <_IO_2_1_stdin_>,
filename=filename@entry=0x60e5bd "<stdin>", flags=flags@entry=0x7fff1d45c0b0) at ../Python/pythonrun.c:857
#16 0x000000000044e998 in PyRun_InteractiveLoopFlags (fp=fp@entry=0x7f99750fb640 <_IO_2_1_stdin_>,
filename=filename@entry=0x60e5bd "<stdin>", flags=flags@entry=0x7fff1d45c0b0) at ../Python/pythonrun.c:777
#17 0x000000000044ed70 in PyRun_AnyFileExFlags (fp=fp@entry=0x7f99750fb640 <_IO_2_1_stdin_>,
filename=filename@entry=0x60e5bd "<stdin>", closeit=closeit@entry=0, flags=flags@entry=0x7fff1d45c0b0)
at ../Python/pythonrun.c:746
---Type <return> to continue, or q <return> to quit---
#18 0x000000000044f904 in Py_Main (argc=<optimized out>, argv=0x7fff1d45c268) at ../Modules/main.c:640
#19 0x00007f9974d5dec5 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#20 0x0000000000578c4e in _start ()
(gdb)
我读到当errno
'路径的组件不存在时,统计函数可以将ENOENT
设置为stat
。但该模块仍然有效,所以路径必须正确,对吗?
我必须做一些令人难以置信的愚蠢事情,但我还没有找到它。
如果重要:使用GCC 4.8.4的Linux Mint 17.1上的Python 2.7.6
答案 0 :(得分:1)
批次代码集errno
,因为多个代码路径可能导致返回相同的错误。因此,除非代码显式返回错误结果,否则errno
中的值应忽略。