Geo*_*rge 4 c haskell ffi inline-c
我正在使用C代码库
typedef void(* wl_notify_func_t) (struct wl_listener *listener, void *data)
//...
struct wl_listener {
struct wl_list link;
wl_notify_func_t notify; //<-- I'd like to return this
};
Run Code Online (Sandbox Code Playgroud)
并使用了Haskell代码
type NotifyFuncT = FunPtr (Ptr C'WlListener -> Ptr () -> IO ())
initializeMyCtx = C.context $ C.baseCtx <> C.funCtx <> mempty {
C.ctxTypesTable = Data.Map.fromList [
(C.Struct "wl_listener", [t|C'WlListener|])
-- ...
, (C.TypeName "wl_notify_func_t", [t|NotifyFuncT|])
]
}
someHaskellFunction :: Ptr C'WlListener -> IO NotifyFuncT
someHaskellFunction ptrToWlListener = do
funPtr <- [C.block| wl_notify_func_t {return $(struct wl_listener * ptrToWlListener)->notify;}|]
return funPtr
Run Code Online (Sandbox Code Playgroud)
不幸的是,我从内联-C代码块中得到一个错误,它本质上说:
unexpected identifier wl_notify_func_t
Run Code Online (Sandbox Code Playgroud)
那么我使用inline-C甚至可以做什么呢?
您错误地使用了上下文.
C.context :: Context -> Q [Dec]
Run Code Online (Sandbox Code Playgroud)
它被称为模板Haskell顶层拼接.你所做的就是定义
intializeMyCtx :: Q [Dec]
Run Code Online (Sandbox Code Playgroud)
这是一个Q是肌动将被执行的初始化上下文,但不是.所以,修复:
type NotifyFuncT = FunPtr (Ptr C'WlListener -> Ptr () -> IO ())
C.context $ C.baseCtx <> C.funCtx <> mempty {
C.ctxTypesTable = Data.Map.fromList [
(C.Struct "wl_listener", [t|C'WlListener|])
-- ...
, (C.TypeName "wl_notify_func_t", [t|NotifyFuncT|])
]
}
Run Code Online (Sandbox Code Playgroud)
其次,someHaskellFunction有点过于复杂.如果你有一个更复杂的功能,那么C.block可能是有保证的,但现在一个人C.exp会做所有事情.
someHaskellFunction :: Ptr C'WlListener -> IO NotifyFuncT
someHaskellFunction ptr = [C.exp| wl_notify_func_t { $(struct wl_listener *ptr)->notify } |]
Run Code Online (Sandbox Code Playgroud)