Как создать структуру C из Python с помощью ctypes?

У меня проблема, аналогичная этому вопросу. Я в основном пытаюсь создать структуры C из Python, используя ctypes.

В Си у меня есть:

typedef struct Point {
    int x;
    int y;
} Point ;

Point* makePoint(int x, int y){
    Point *point = (Point*) malloc(sizeof (Point));
    point->x = x;
    point->y = y;
    return point;
}

void freePoint(Point* point){
    free(point);
}

В то время как в Python у меня есть:

    class Point(ct.Structure):
        _fields_ = [
            ("x", ct.c_int64),
            ("y", ct.c_int64),
        ]


    lib = ct.CDLL("SRES.dll")

    lib.makePoint.restype = ct.c_void_p

    pptr = lib.makePoint(4, 5)
    print(pptr)

    p = Point.from_address(pptr)
    print(p)
    print(p.x)
    print(p.y)

В настоящее время это выводит кучу указателей:

2365277332448
<__main__.Point object at 0x00000226D2C55340>
21474836484
-8646857406049613808

Как я могу вместо этого заставить этот вывод возвращать числа, которые я ввел, т.е.

2365277332448
<__main__.Point object at 0x00000226D2C55340>
4
5


person CiaranWelsh    schedule 26.01.2021    source источник


Ответы (1)


Проблема была c_int64. После изменения на c_int32 все работает нормально. Вы можете взять c_int64 как long со стороны C.

Кроме того, вы можете сделать

lib.makePoint.restype = ct.POINTER(Point)
p = lib.makePoint(4, 5)
print(p.contents.x)
print(p.contents.y)
person ghchoi    schedule 26.01.2021
comment
Я понимаю: AttributeError: 'Point' object has no attribute 'contents' - person CiaranWelsh; 26.01.2021
comment
@CiaranWelsh А... Затем p['x'] и p['y']. Вы их пробовали? - person ghchoi; 26.01.2021
comment
@CiaranWelsh pptr.contents.x может сработать. Я думаю... - person ghchoi; 26.01.2021
comment
Нет, я предполагал, что запись через точку будет работать. p['x'] вызывает TypeError: 'Point' object is not subscriptable. Спасибо за мозговой штурм вместе со мной. - person CiaranWelsh; 26.01.2021
comment
@CiaranWelsh Боже... Позвольте мне попробовать... - person ghchoi; 26.01.2021
comment
@CiaranWelsh Проблема была типа... - person ghchoi; 26.01.2021
comment
Aaaah старая классическая проблема ctypes. Мне понадобилась бы целая вечность, чтобы понять это, спасибо. - person CiaranWelsh; 26.01.2021
comment
@CiaranWelsh Спасибо, что приняли! - person ghchoi; 26.01.2021
comment
Лучше не полагаться на встроенные типы c для длины слова на стороне C уравнения. Для этого в stdint.h есть int32_t/int64_t и другие. - person Shawn; 26.01.2021
comment
Кроме того, ctypes имеет c_int параллели C int. Используйте соответствующие типы. - person Mark Tolonen; 26.01.2021