Передавая указатель на функцию в под
Я пытаюсь переделать модуль Misaka в ctypes, но когда я пытаюсь использовать bufputs, я получаю ошибку (см. Конец 2-го примера кода). Когда я передаю указатель на функцию, я использую pointer(b)
. Это не работает, и byref(b)
тоже не работает.
Это сигнатура функции:
/* bufputs • appends a NUL-terminated string to a buffer */
void
bufputs(struct buf *, const char*);
Вот мой код:
>>> from ctypes import *
>>> sundown = cdll.LoadLibrary('./libsundown.so.1')
>>> sundown
<CDLL './libsundown.so.1', handle 1e2f190 at 1bea0d0>
>>> # OUT: <CDLL './libsundown.so.1', handle 2840d80 at 2797290>
>>> class buf(Structure):
... _fields_ = [
... ('data', c_char_p),
... ('size', c_size_t),
... ('asize', c_size_t),
... ('unit', c_size_t),
... ('ref', c_int)]
...
>>> sundown.bufnew.argtypes = [c_size_t]
>>> sundown.bufnew.restype = buf
>>> b = sundown.bufnew(c_size_t(1024))
>>> sundown.bufputs.argtypes = [POINTER(buf), c_char_p]
>>> s = c_char_p('this is a test')
>>> sundown.bufputs(pointer(b), s)
python2: malloc.c:3574: mremap_chunk: Assertion `((size + offset) & (mp_.pagesize-1)) == 0' failed.
Aborted
Я не могу понять, что я сделал не так.1 ответ:
Решение ОП, первоначально опубликованное в вопросе
class buf(Structure): _fields_ = [ ('data', c_char_p), ('size', c_size_t), ('asize', c_size_t), ('unit', c_size_t), ('ref', c_int) ] buf_p = POINTER(buf) sundown.bufnew.argtypes = [c_size_t] sundown.bufnew.restype = buf_p sundown.bufgrow.argtypes = [buf_p, c_size_t] sundown.bufputs.argtypes = [buf_p, c_char_p] ib = buf() # ctypes does this internally: # memset(byref(ib), 0x0, sizeof(buf)) text = 'this is some text' ib.data = text ib.size = len(text) ob = sundown.bufnew(128) sundown.bufgrow(ob, int(math.ceil(ib.size * 1.4))) sundown.bufputs(ob, 'test')