这是一个简单的h
文件:
/* file marchingcubes.h */
typedef struct {
double x,y,z;
} XYZ;
要在Haskell中定义类似的类型,我使用hsc2hs
。我写这个文件CTypes.hsc
:
{-# LANGUAGE ForeignFunctionInterface #-}
module CTypes
where
import Foreign
import Foreign.C.Types
#include "marchingcubes.h"
data CXYZ = CXYZ {
__x :: CDouble
, __y :: CDouble
, __z :: CDouble
}
instance Storable CXYZ where
sizeOf __ = #{size XYZ}
alignment __ = #{alignment XYZ}
peek ptr = do
x' <- #{peek XYZ, x} ptr
y' <- #{peek XYZ, y} ptr
z' <- #{peek XYZ, z} ptr
return CXYZ { __x = x'
, __y = y'
, __z = z' }
poke ptr (CXYZ r1 r2 r3)
= do
#{poke XYZ, x} ptr r1
#{poke XYZ, y} ptr r2
#{poke XYZ, z} ptr r3
使用hs
转换为hsc2hs
之后和之后没问题。
现在我有另一个包含静态数组的结构:
typedef struct {
XYZ p[3];
} TRIANGLE;
如何在hsc
文件中定义Haskell中的类似类型?我可以拥有类似的东西:
data CTRIANGLE = CTRIANGLE {
__p :: [CXYZ]
}
?我如何定义Storable
实例?我发现了几个关于阵列和FFI的问题,但没有任何东西允许我解决这个问题。
我已经完成了:
data CTRIANGLE = CTRIANGLE {
__p :: [CXYZ]
}
instance Storable CTRIANGLE where
sizeOf __ = #{size TRIANGLE}
alignment __ = #{alignment TRIANGLE}
peek ptr = do
p' <- peekArray 3 $ #{ptr TRIANGLE, p} ptr
return CTRIANGLE { __p = p' }
poke ptr (CXY r1) = do
pokeArray (#{ptr TRIANGLE, p} ptr) r1
hsc2hs
生成:
instance Storable CTRIANGLE where
sizeOf __ = (72)
{-# LINE 37 "CTypes.hsc" #-}
alignment __ = 8
{-# LINE 38 "CTypes.hsc" #-}
peek ptr = do
p' <- peekArray 3 $ (\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr
{-# LINE 40 "CTypes.hsc" #-}
return CTRIANGLE { __p = p' }
poke ptr (CXY r1) = do
pokeArray ((\hsc_ptr -> hsc_ptr `plusPtr` 0) ptr) r1
{-# LINE 43 "CTypes.hsc" #-}
现在我必须测试一下是否有效。
答案 0 :(得分:2)
我在更新中提供的代码有效:)
在marchingcubes.hsc
:
data CTRIANGLE = CTRIANGLE {
__p :: [CXYZ]
} deriving Show
instance Storable CTRIANGLE where
sizeOf __ = #{size TRIANGLE}
alignment __ = #{alignment TRIANGLE}
peek ptr = do
p' <- peekArray 3 $ #{ptr TRIANGLE, p} ptr
return CTRIANGLE { __p = p' }
poke ptr (CTRIANGLE r1) = do
pokeArray (#{ptr TRIANGLE, p} ptr) r1
foreign import ccall unsafe "testTriangle" c_testTriangle
:: CDouble -> CDouble -> CDouble
-> IO (Ptr CTRIANGLE)
现在让我们检查一下。我做了一个文件marchingcubes.c
:
#include <stdlib.h>
#include "marchingcubes.h"
TRIANGLE* testTriangle(double a, double b, double c){
XYZ xyz;
xyz.x = a;
xyz.y = b;
xyz.z = c;
TRIANGLE *tri = malloc(sizeof(TRIANGLE));
tri[0].p[0] = xyz;
tri[0].p[1] = xyz;
tri[0].p[2] = xyz;
return tri;
}
我做了一个模块:
module Lib
where
import CTypes
import Foreign
someFunc :: IO CTRIANGLE
someFunc = do
ptr <- c_testTriangle 1 2 3
peek ptr
测试:
Prelude Lib> someFunc
CTRIANGLE {__p = [CXYZ {__x = 1.0, __y = 2.0, __z = 3.0},CXYZ {__x = 1.0, __y = 2.0, __z = 3.0},CXYZ {__x = 1.0, __y = 2.0, __z = 3.0}]}
这是期望的结果:)
不要忘记
include-dirs: C
C-sources: C/marchingcubes.c
在cabal
文件中。