Я пытаюсь вызвать функцию C
от Haskell
с использованием c2hs
.Как вызвать функцию C, которая использует обратный вызов в Haskell?
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'. –