inline-c:“`Type` 不能在外部调用中编组”
inline-c : "`Type` cannot be marshalled in a foreign call"
设置
C 枚举类型由 c2hs 呈现为 Haskell,并带有 Storable
正确编译的实例 (TypesC2Hs.chs
)。我将此不合格导入到我为 inline-c
上下文 (Internal.hs
) 分配的模块中。 c2hs 生成的 .hs
模块和 Internal.hs
都由 InlineC.hs
导入,另一个 inline-c
模块包含包装 C 调用的准引号。
TypesC2Hs.hs -------------
| |
V V
Internal.hs -------> InlineC.hs
问题
InlineC.hs
抱怨无法编组此类型:"Unacceptable argument type in foreign declaration: ‘DMBoundaryType’ cannot be marshalled in a foreign call When checking declaration:"
这是怎么回事?这是 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
C enum
不是 marshallable foreign type, that is what compiler tries to tell you. To work around it, pass it as a CInt
using fromEnum
(looks like c2hs
now supports it via hooks,但我没试过。)
设置
C 枚举类型由 c2hs 呈现为 Haskell,并带有 Storable
正确编译的实例 (TypesC2Hs.chs
)。我将此不合格导入到我为 inline-c
上下文 (Internal.hs
) 分配的模块中。 c2hs 生成的 .hs
模块和 Internal.hs
都由 InlineC.hs
导入,另一个 inline-c
模块包含包装 C 调用的准引号。
TypesC2Hs.hs -------------
| |
V V
Internal.hs -------> InlineC.hs
问题
InlineC.hs
抱怨无法编组此类型:"Unacceptable argument type in foreign declaration: ‘DMBoundaryType’ cannot be marshalled in a foreign call When checking declaration:"
这是怎么回事?这是 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
C enum
不是 marshallable foreign type, that is what compiler tries to tell you. To work around it, pass it as a CInt
using fromEnum
(looks like c2hs
now supports it via hooks,但我没试过。)