我正在嘗試使用c2hs
從Haskell
調用以下C
函數。如何調用在Haskell中使用回調的C函數?
void rd_kafka_conf_set_rebalance_cb (
rd_kafka_conf_t *conf,
void (*rebalance_cb) (rd_kafka_t *rk,
rd_kafka_resp_err_t err,
rd_kafka_topic_partition_list_t *partitions,
void *opaque));
我不熟悉c2hs
,並且在聲明綁定時遇到麻煩。
這是我已經試過:
--callback type
type RebalanceCbFun =
Ptr RdKafkaT -> CInt -> Ptr RdKafkaTopicPartitionListT -> Ptr Word8 -> IO()
foreign import ccall safe "wrapper"
mkRebalanceCallback :: RebalanceCbFun -> IO (FunPtr RebalanceCbFun)
foreign import ccall unsafe "rd_kafka.h &rd_kafka_conf_set_rebalance_cb"
rdKafkaConfSetRebalanceCb :: Ptr RdKafkaConfT -> FunPtr RebalanceCbFun -> IO()
不過,我有以下錯誤而編譯此代碼:
Unacceptable type in foreign declaration:
‘Ptr RdKafkaConfT
-> FunPtr
(Ptr RdKafkaT
-> Int32 -> Ptr RdKafkaTopicPartitionListT -> Ptr Word8 -> IO())
-> IO()’ cannot be marshalled in a foreign call
A foreign-imported address (via &foo) must have type (Ptr a) or (FunPtr a)
When checking declaration:
foreign import ccall unsafe "static rd_kafka.h &rd_kafka_conf_set_rebalance_cb" rdKafkaConfSetRebalanceCb
:: Ptr RdKafkaConfT -> FunPtr RebalanceCbFun -> IO()
我不明白是什麼部分缺失Ptr
或FunPtr
這裏。 我也試過整個rdKafkaConfSetRebalanceCb
包裝成FunPtr
,如:
foreign import ccall unsafe "rd_kafka.h &rd_kafka_conf_set_rebalance_cb"
rdKafkaConfSetRebalanceCb :: FunPtr (Ptr RdKafkaConfT -> FunPtr RebalanceCbFun -> IO())
不知道它是有道理的,儘管它編譯... 但我不知道如何使用這個功能,這就是我嘗試(這是我想在結束了簽名):
kafkaConfSetRebalanceCb :: RdKafkaConfTPtr -> RebalanceCbFun -> IO()
kafkaConfSetRebalanceCb conf cb = do
cb' <- mkRebalanceCallback cb
withForeignPtr conf $ \c -> rdKafkaConfSetRebalanceCb c cb'
return()
現在抱怨我沒有要調用的函數,只是一個指針的函數(因爲FunPtr
的包裝)。
你能告訴我如何C
綁定可以正確完成上面的C
簽名?
未來訪問者注意:C函數將會像這樣調用Haskell代碼,不能導入'unsafe'。 –