【问题标题】:Python/Ctypes - Segmentation Fault on Access to Pointer (to Array)Python/Ctypes - 访问指针(到数组)时出现分段错误
【发布时间】:2018-10-04 18:52:57
【问题描述】:

This is similar except I do not get a single value and instead segfault on [0] or .contents

如何从 Python 访问“数组”中的元素?

在 C 中我有类似的东西

#pragma pack(push, 1)
struct Data {
    int i;
    int *array;
};
#pragma pack(pop)

typedef struct {
    bool (* const get)   (struct Data*, const char *source);
    void (* const print) (struct Data*);
} DataFn;
extern DataFn const DATAFUNC;

在 Python 中我有类似的东西

class Data(ctypes.Structure):
    _fields_ = [
        ("i", ctypes.c_int),
        ("array",   ctypes.POINTER(ctypes.c_int))
    ]

class DATA_FN(ctypes.Structure):
    _fields_ = [
        ("get"   , ctypes.CFUNCTYPE(
                                          ctypes.c_bool,
                                          ctypes.POINTER(Data),
                                          ctypes.c_char_p)),
        ("print" , ctypes.CFUNCTYPE(None, 
                                          ctypes.POINTER(Data)))
    ]

从 python 我可以做类似的事情 ..

    with open("xx0c.exx", "rb") as f:
        fdata = f.read()
        dfn.get(ctypes.byref(data),f fdata)
        dfn.print(ctypes.byref(data))
        print(data)
        print(data.i)                #7, correct
        #print(data.array.contents)  #segfault
        #print(data.array)           #segfault
        ptr = ctypes.pointer(data)
        print(ptr.contents.array[0]) #segfault

从 python 调用的 C 函数将打印 .. 这是正确的

i = 7

数组 = 0x6ffff360034

数组 0 = 20

数组 1 = 27a40

数组 2 = 127e20

数组 3 = 128ae0

数组 4 = 47e850

数组 5 = 57ec30

数组 6 = 580230

我可以看到 python 中的数组不在 C 中的数组附近。

按要求提供示例 C 代码。这些是静态的,但可以通过 DATAFUNC 访问它们。使用这些的 C 程序很好。

static bool getdata(struct Data *d, const char *filedata) {
    bool good = false;
    if (d != NULL && filedata != NULL) {
        d -> i       = (int32_t)filedata[0];
        d -> array   = (uint32_t*)(filedata + sizeof(int32_t));
        if ( d->i > 0 ) {
          good = true;
        }
    }
    return good;
}

static void printdata(struct Data *d) {
    if (d == NULL) {
        return;
    }
    printf("i = %i\n", d -> i);
    printf("array = %p\n", d -> array);
    unsigned int i;
    for (i = 0; i < d -> i; i++) {
        printf("array %i = %x\n", i, d -> array[i]);
    }
}

【问题讨论】:

  • 能否请您也展示您的 C 代码?可能是错误存在。
  • 我愿意,但作为警告,它对于包含它的 C 程序可以正常工作(它也特定于二进制文件格式)。
  • 您是在 Python 函数中读取文件吗?因为那时变量 file 将是该函数的本地变量,并且它的生命周期在函数结束时结束,从而使指向数据的指针无效。
  • 是的,它已在函数中读取。此处发布的部分在技术上在脚本中一起出现,但为了在帖子中格式化并显示每行的输出而被分段。
  • 那么这很可能是您的问题。动态分配内存以保存数据的副本,并添加函数以在不再需要时释放此数据。

标签: python c pointers segmentation-fault ctypes


【解决方案1】:

我已经通过将 pack 添加到 python 结构中解决了这个问题,如下所示。

class Data(ctypes.Structure):
    _pack_   = 1
    _fields_ = [
        ("i", ctypes.c_int),
        ("array",   ctypes.POINTER(ctypes.c_int))
    ]

这会修复所有问题,并在添加循环以遍历数组后给出 .. 的输出。

number of offsets = 7
offsets = 0x6ffff360034
offset 0 = 20
offset 1 = 27a40
offset 2 = 127e20
offset 3 = 128ae0
offset 4 = 47e850
offset 5 = 57ec30
offset 6 = 580230
<__main__.Data object at 0x6ffffd5f400>
7
<__main__.LP_c_int object at 0x6ffffd5f488>
0x20
0x27a40
0x127e20
0x128ae0
0x47e850
0x57ec30
0x580230

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2011-05-24
    • 2017-12-13
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    相关资源
    最近更新 更多