#python #c #ctypes
#python #c #ctypes
Вопрос:
>>> from ctypes import *
>>> import ctypes.util
>>> libc = CDLL("libc.so.6")
>>> libc.printf("%cn", 104)
h
2
>>> libc.islower(104) # Works fine
512
>>> libc.islower.restype = c_bool # But when i do this...
>>> libc.islower(104)
False
>>> c_bool(512)
c_bool(True)
лично я думаю, что ‘h’ в нижнем регистре..
Это ошибка в ctypes, или я делаю что-то неправильно?
Комментарии:
1. В C любое ненулевое значение равно true. Таким образом, 512 является прекрасным показателем того, что h в нижнем регистре. Внутренне ctypes обычно реализуется в виде таблицы растровых изображений, по одному на символ. Здесь должен использоваться бит 9 для нижнего регистра.
2. @Gene Я думаю, он спрашивает о
False
последней команде.3. о, действительно, но когда я заменяю возвращаемый тип на c_bool, он возвращает false
4. Вероятно, c_bool ошибочно объявлен как char, поэтому 2 ^ 9, принудительно преобразованные в c_bool, теряют 1 бит.
5. Предлагаю удалить тег C.
Ответ №1:
restype
здесь не просто указать тип вывода Python, но, что наиболее важно, указать, какой тип C следует ожидать, и, следовательно, как его маршалировать. islower
возвращает значение int
, которое обычно имеет ширину 4 байта; если вы говорите, что оно возвращает значение bool
(которое обычно составляет 1 байт), вы нарушаете ожидания кода маршалинга.
На этот раз вы получили неверный результат (вероятно, потому, что на вашей платформе код возврата отправляется в регистр, и поэтому он просто принимает младшие 8 бит), на другой платформе или для другого типа это может легко привести к поломке стека и, следовательно, к сбою вашего процесса.
Итак: не делайте этого. Всегда уважайте типы C API и конвертируйте после вызова.