【问题标题】:python ctypes and sysctlpython ctypes 和 sysctl
【发布时间】:2009-04-17 10:24:38
【问题描述】:

我有以下代码

import sys
from ctypes import *
from ctypes.util import find_library

libc = cdll.LoadLibrary(find_library("c"))
CTL_KERN = 1
KERN_SHMMAX = 34
sysctl_names = {
    'memory_shared_buffers' : (CTL_KERN, KERN_SHMMAX),
    }

def posix_sysctl_long(name):
    _mem = c_uint64(0)
    _arr = c_int * 2
    _name = _arr()
    _name[0] = c_int(sysctl_names[name][0])
    _name[1] = c_int(sysctl_names[name][1])
    result = libc.sysctl(_name, byref(_mem), c_size_t(sizeof(_mem)), None, c_size_t(0))
    if result != 0:
        raise Exception('sysctl returned with error %s' % result)
    return _mem.value

print posix_sysctl_long('memory_shared_buffers')

产生以下结果:

Traceback (most recent call last):
  File "test.py", line 23, in <module>
    print posix_sysctl_long('memory_shared_buffers')
  File "test.py", line 20, in posix_sysctl_long
    raise Exception('sysctl returned with error %s' % result)
Exception: sysctl returned with error -1

我想我做错了什么。什么是正确的调用约定?我怎样才能知道到底出了什么问题?

【问题讨论】:

    标签: python c linux ctypes


    【解决方案1】:

    您没有为 sysctl 函数提供正确的值。 sysctl() 参数的详细信息可以在here找到。

    这是您的错误:

    • 您忘记了 nlen 参数(第二个参数)
    • oldlenp 参数是指向大小的指针,而不是直接指向大小的指针

    这是正确的功能(稍有改进):

    def posix_sysctl_long(name):
        _mem = c_uint64(0)
        _def = sysctl_names[name]
        _arr = c_int * len(_def)
        _name = _arr()
        for i, v in enumerate(_def):
            _name[i] = c_int(v)
        _sz = c_size_t(sizeof(_mem))
        result = libc.sysctl(_name, len(_def), byref(_mem), byref(_sz), None, c_size_t(0))
        if result != 0:
            raise Exception('sysctl returned with error %s' % result)
        return _mem.value
    

    【讨论】:

    • 非常感谢。确实,不知何故我忘记了第二个参数:-(我的原始版本使用 sysctlbyname,不需要该参数。不幸的是,linux 似乎不支持该功能。
    猜你喜欢
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多