#python #ctypes #ffi
Вопрос:
Если у меня есть следующая библиотека C
#include <stdint.h>
int64_t* foo(int64_t *x) {
return x;
}
и я вызываю функцию из типов ctypes Python следующим образом:
ptr = (ctypes.c_int64 * 100)()
rval = api.foo(ptr)
Наивно я бы предположил , что могу просто assertEqual(rval, ptr)
, но это не удается. Печать rval
и ptr
соответственно я получаю
<reference_project.LP_c_longlong object at 0x0000021A563BBDC0>
<tests.c_longlong_Array_100 object at 0x0000021A563BBF40>
Как я могу сравнить ptr
и rval
для равенства с Python?
Комментарии:
1. Я ожидал, что это сработает, если вы исправите типы, но нет. Похоже, что в ctypes просто нет сравнения указателей.
2. На самом деле, похоже, что ctypes вообще не реализует никаких операций сравнения для любых типов.
3. (В «исправьте типы» я включал преобразование
ptr
в фактический указатель — в настоящее время это массив.actual_ptr = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_int64))
выполнит это преобразование.)4. Исправлен пример; Я допустил ошибку, когда упрощал свой код для SO.
Ответ №1:
Отвечая на мой собственный вопрос, приведение указателей c_void_p
и взятие .value
, похоже, делают свою работу:
ptr_via_void = ctypes.cast(ptr, ctypes.c_void_p).value
rval_via_void = ctypes.cast(rval, ctypes.c_void_p).value
print(ptr_via_void) # 2373661818336
print(rval_via_void) # 2373661818336
assertEqual(ptr_via_void, rval_via_void)
Однако просто опустить .value
не работает:
ptr_via_void = ctypes.cast(ptr, ctypes.c_void_p)
rval_via_void = ctypes.cast(rval, ctypes.c_void_p)
print(ptr_via_void) # c_void_p(1988667444176)
print(rval_via_void) # c_void_p(1988667444176)
# Although both print the same value, this FAILS:
assertEqual(ptr_via_void, rval_via_void)
Я не могу поверить, что, по-видимому, нет лучшего способа.
Комментарии:
1. Даже
c_int(1) == c_int(1)
возвращаетсяFalse
, ноc_int(1).value == c_int(1).value
возвращаетсяTrue
.