为什么在使用ctypes调用libc的environ时Python会崩溃?

6 投票
2 回答
660 浏览
提问于 2025-04-17 11:57

我在Ubuntu和ArchLinux上都测试过这个,结果是

from ctypes import *
libc = CDLL('libc.so.6')
libc.environ()
Segmentation fault

这是为什么呢?

2 个回答

0

下面是如何在Ubuntu上使用ctypes打印C语言环境的方法:

#!/usr/bin/env python2
import ctypes

libc = ctypes.CDLL(None)
environ = ctypes.POINTER(ctypes.c_char_p).in_dll(libc, 'environ')
for envvar in iter(iter(environ).next, None):
    print envvar

输出结果

LC_PAPER=en_GB.UTF-8
LC_ADDRESS=en_GB.UTF-8
CLUTTER_IM_MODULE=xim
LC_MONETARY=en_GB.UTF-8
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
SESSION=ubuntu
...
7

如果我没理解错,environ其实是一个char**,而不是一个函数。想要获取环境变量的话,按照这篇文章的说法,你可以这样做:

from ctypes import *
libc = CDLL('libc.so.6')
environ = c_char_p.in_dll(libc, 'environ')

不过这个方法对我来说返回的是'c_void_p(None)',我也不太明白为什么会这样(我知道我只声明了一个char *,但既然返回的是None,那就没有东西可以解引用了)。

无论如何,你还是可以用“python”的方式来做:

import os
print os.environ

或者,如果你想在environ中用ctypes查找特定的字符串,针对某个函数,你需要重新定义默认的返回类型:

from ctypes import *
libc = CDLL('libc.so.6')
getenv = libc.getenv
getenv.restype = c_char_p
print getenv('HOME')

撰写回答