inline-c:“`type`无法在外国电话中编组”

时间:2016-05-26 17:25:19

标签: c haskell ffi c2hs

设置

由c2hs呈现到Haskell中的C枚举类型,其中包含正确编译的Storable实例(TypesC2Hs.chs)。我将此不合格的内容导入我为inline-c上下文(Internal.hs)分配的模块中。 c2hs生成的.hs模块和Internal.hs都由InlineC.hs导入,另一个inline-c模块包含C调用的quasiquotes。

TypesC2Hs.hs ------------- 
    |                    |
    V                    V
Internal.hs -------> InlineC.hs

问题

InlineC.hs抱怨此类型无法编组:“外部声明中不可接受的参数类型:'DMBoundaryType'无法在外部调用中编组时检查声明:”

发生了什么事?这是inline-c第一次给我这个错误的类型。

我应该注意不需要直接解除引用的其他类型,例如: newtype DM = DM (Ptr DM) deriving Storable,使用上述方法可以正常工作。

提前致谢

TypesC2Hs.chs

{# enum DMBoundaryType as DMBoundaryType {underscoreToCase} deriving (Eq, Show) #}

instance Storable DMBoundaryType where
  sizeOf _ = {# sizeof DMBoundaryType #}
  alignment _ = {# alignof DMBoundaryType #}
  peek = peek
  poke = poke

Internal.hs

{-# LANGUAGE QuasiQuotes, TemplateHaskell ,GeneralizedNewtypeDeriving, StandaloneDeriving ,DeriveDataTypeable, DataKinds, OverloadedStrings #-}

module Internal where

import TypesC2Hs

import qualified Language.C.Inline         as C
import qualified Language.C.Types          as CT
import           Language.C.Inline.Context

import qualified Language.Haskell.TH       as TH

import           Data.Monoid               ((<>), mempty)
import qualified Data.Map                  as Map


ctx :: Context
ctx = baseCtx <> funCtx <> vecCtx <> bsCtx <> pctx where
  pctx = mempty {ctxTypesTable = typesTable}


typesTable :: Map.Map CT.TypeSpecifier TH.TypeQ  
typesTable = Map.fromList
              [ (CT.TypeName "DMBoundaryType", [t| DMBoundaryType |])  ]

InlineC.hs

dmdaCreate1d0' cc bx m dof s =
   withPtr ( \ dm -> [C.exp|int{DMDACreate1d($(int c),
                                              $(DMBoundaryType bx),
                                              $(PetscInt m),
                                              $(PetscInt dof),
                                              $(PetscInt s),
                                              NULL,
                                              $(DM* dm))}|]  )
  where c = unComm cc

1 个答案:

答案 0 :(得分:6)

C enum不是marshallable foreign type,这是编译器试图告诉你的。要解决此问题,请使用CInt将其作为fromEnum传递(看起来c2hs现在通过hooks支持它,但我从未尝试过。)