Вычисление структуры из C в Haskell с использованием Inline-C
Я пытаюсь упорядочить следующий тип структуры между C и Haskell через inline-C:
//defined in wayland-server-core.h
struct wl_listener {
struct wl_list link;
wl_notify_func_t notify;
};
//such that:
typedef void (*wl_notify_func_t)(struct wl_listener *listener, void *data);
Согласно документации inline-C:
inline-c также может обрабатывать определяемые пользователем структуры и перечисления, при условии, что они являются экземплярами Storable и что вы сообщаете inline-c о них, используя контексты.
Здесь я пытаюсь сделать именно это:
-- In some module:
data C'WlListener -- Our (opaque) struct type in Haskell
initializeMyCtx = C.context $ C.baseCtx <> C.funCtx <> mempty {
C.ctxTypesTable = Data.Map.fromList [
-- ...
, (C.Struct "wl_listener", [t|C'WlListener|])
-- ...
]
}
-- In a different module:
initializeMyCtx
C.include "<wayland-server.h>"
C.include "<wayland-server-core.h>"
-- | We make C'WlListener an instance of Storable so we can conveniently
-- | pass it from C to Haskell and back via inline-C.
instance Storable C'WlListener where
sizeOf _ = fromIntegral $ [C.pure| int { sizeof(struct wl_listener) }|]
alignment _ = fromIntegral $ [C.pure| int { alignof(struct wl_listener) }|]
peek = error "peek not implemented for C'WlListener"
poke _ _ = error "poke not implemented for C'WlListener"
Теперь, когда я пытаюсь использовать это в Haskell
-- In a third module:
someIOFunc :: IO ()
someIOFunc = do
-- Initialize an empty struct (which intializes its members to 0 by default) to pass around from Haskell
myListener <- [C.exp| struct wl_listener { struct wl_listener listener }|]
-- ...
Я получаю следующую ошибку:
• Unacceptable result type in foreign declaration:
‘C'WlListener’ cannot be marshalled in a foreign call
• When checking declaration:
foreign import ccall safe "inline_c_McWayFace_2" inline_c_ffi_6989586621679102285
:: IO C'WlListener
|
71 | myListener <- [C.exp| struct wl_listener { struct wl_listener listener }|]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^