4

Python の CFFI で C 関数にポインタを渡すにはどうすればよいですか?

たとえば、ラッピングしているライブラリに 2 つの関数があるとします。

void some_function(void (*callback)()) {
    callback();
}

void some_callback() {
    printf("callback!\n");
}

some_functionを渡すにはどうすればよいsome_callbackですか? たとえば、次のようなものです。

from mylib._ffi import lib
lib.some_function(lib.some_callback)

Python 関数をコールバックでラップするために使用できることはわかっていffi.callback(…)ますが、C 関数の型シグネチャなどの重複を避けることができるかどうか疑問に思っています。

4

1 に答える 1

4

最新バージョンの cffi では、アウトオブライン モードで次のことができます。

lib.some_function(ffi.addressof(lib, "some_callback"))

または、これは古いcffiでも機能します。関数としてではなく、定数関数ポインターとして「some_callback」を含めるようにcdefを微調整する必要があります。

ffi.cdef("void (*const some_callback)();")
lib.some_function(lib.some_callback)

これが魔法のように思える場合は、より冗長ですが、より明確な解決策は次のようになります。

ffi.cdef("""
    typedef void (*my_callback_t)();
    my_callback_t get_some_callback(void);
""")
ffi.set_source("example",  # <- or, ffi.verify(
"""
    // declare get_some_callback() explicitly here:
    typedef void (*my_callback_t)();
    static my_callback_t get_some_callback(void) {
        return &some_callback;
    }
""")

some_callback = lib.get_some_callback()
lib.some_function(some_callback)
于 2015-06-12T19:47:21.340 に答える