gpt4 book ai didi

haskell - 如何调用在 Haskell 中使用回调的 C 函数?

转载 作者:行者123 更新时间:2023-12-01 12:29:13 25 4
gpt4 key购买 nike

我正在尝试使用 c2hsHaskell 调用以下 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,并且在声明绑定(bind)时遇到了麻烦。

这是我试过的:

--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 ()

我不明白这里缺少什么部分 PtrFunPtr 。我还尝试将整个 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 绑定(bind)吗?

最佳答案

以下文件对我来说编译得很好(使用 ghc -c Test.hs)。唯一真正的区别是我省略了外部导入中的 &

{-# LANGUAGE ForeignFunctionInterface #-}
module Test where
import Data.Word
import Foreign.C.Types
import Foreign.Ptr
import Foreign.ForeignPtr

newtype RdKafkaT = RdKafkaT (Ptr RdKafkaT)
newtype RdKafkaConfT = RdKafkaConfT (Ptr RdKafkaConfT)
newtype RdKafkaTopicPartitionListT = RdKafkaTopicPartitionListT (Ptr RdKafkaTopicPartitionListT)

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 ()

kafkaConfSetRebalanceCb :: ForeignPtr RdKafkaConfT -> RebalanceCbFun -> IO ()
kafkaConfSetRebalanceCb conf cb = do
cb' <- mkRebalanceCallback cb
withForeignPtr conf $ \c -> rdKafkaConfSetRebalanceCb c cb'

关于haskell - 如何调用在 Haskell 中使用回调的 C 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36007149/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com