Cスレッドからctypes経由で呼び出されたときに失敗したMalloc

PythonのCTypesを使って共有ライブラリにバインドしています。このライブラリに登録されているコールバックがあります。このコールバックは、ライブラリ自体が作成するスレッドのコンテキストで呼び出されます。私は、コールバック内から libc.malloc() libc = cdll.LoadLibrary( 'libc.so.6'))をコールすると、偽の値を返します。 NULL ではなく、逆参照するとsegfaultを引き起こすアドレスです。

誰でも私に何が起こっているのかについての洞察を提供することができますか、あるいは同じ方法で malloc()を呼び出し、それがそれらのために働くことを教えてください。

0

2 答え

ctypesが整数ではなくポインタを返すべきであることを知っているように、malloc呼び出しを適切にアノテートしていますか? (もしあなたが64bitボックスで作業しているのであれば、二重に?)

1
追加された

以下のコードはWindows上で動作します。 Linuxでも似ているはずです。少なくとも32ビットシステムでは、明示的な argtypes/restype 属性が設定されていなくても動作します。

from ctypes import *

crt = CDLL('msvcrt')
malloc = crt.malloc
malloc.argtypes = [c_size_t]
malloc.restype = c_void_p
free = crt.free
free.argtypes = [c_void_p]
free.restype = None

n = cast(malloc(10),POINTER(c_ubyte))
for i in range(10):
    print '{:02X}'.format(n[i]),
free(n)

コールバックについて言及して以来、コールバックが使用されている間、そのコールバックへの参照を保持してください。つまり、次のように呼ぶことはありません。

set_callback(CFUNCTYPE(...)(callback_func))

CFUNCTYPEオブジェクトは、コールバックの設定直後に破棄されます。代わりに:

@CFUNCTYPE(...)
def callback_func(...)
    ...

set_callback(callback_func)

このデコレータフォームは、Python関数オブジェクトを、モジュール(またはメソッドの場合はクラス)の存続期間中のctypesコールバックオブジェクトで置き換えます。

0
追加された