3

を使用して次のC関数を呼び出そうとしています。Haskellc2hs

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どの部分が欠けているか、ここがわかりませんFunPtrrdKafkaConfSetRebalanceCbまた、全体を次のようにラップしようとしました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

4

1 に答える 1

4

次のファイルは、私にとっては問題なくコンパイルされます( を使用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'
于 2016-03-15T09:47:27.363 に答える