【发布时间】:2016-03-15 09:25:17
【问题描述】:
我正在尝试使用c2hs 从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 绑定吗?
【问题讨论】:
-
未来访问者请注意:不能像这样将回调到 Haskell 代码中的 C 函数导入
unsafe。