我目前正在使用Haskell绑定到HDF5 C库.像许多C库一样,这个库在函数调用中使用了许多指针.
通常的"最佳实践"为Haskell的分配和释放C资金功能遵循支架图案,如alloca,withArray等.在使用它们时,我经常进入几个嵌套的括号内.例如,以下是HDF5绑定的一小段摘录:
selectHyperslab rID dName = withDataset rID dName $ \dID -> do
v <- withDataspace 10 $ \dstDS -> do
srcDS <- c'H5Dget_space dID
dat <- alloca3 (0, 1, 10) $ \(start, stride, count) -> do
err <- c'H5Sselect_hyperslab srcDS c'H5S_SELECT_SET start stride count nullPtr
-- do some work ...
return value
alloca3 (a, b, c) action =
alloca $ \aP -> do
poke aP a
alloca $ \bP -> do
poke …Run Code Online (Sandbox Code Playgroud) 这是我想要的用例:
我有一个包含单个模块的包,它可以读取HDF5文件,并将一些数据写入Haskell记录.为了完成这项工作,库使用该bindings-hdf5包.这是我的阴谋集团build-depends. reader-types是我写的一个模块,它定义了包含读入数据的Haskell记录的类型.
build-depends: base >=4.7 && <4.8
, text
, vector
, containers
, bindings-hdf5
, reader-types
Run Code Online (Sandbox Code Playgroud)
请注意,我的cabal文件当前不使用extra-libraries或ghc-options.src/Mabel.hs只要我指定所需的hdf5_hl库,我就可以在ghci中加载我的模块:
ghci src/Mabel.hs -lhdf5_hl -L/long/nixos/path/lib
Run Code Online (Sandbox Code Playgroud)
在ghci中,我可以很好地运行我的功能.
现在,我想要做的是将这个库/模块编译成一个单独的编译文件,稍后我可以在另一个Haskell程序中加载GHC API.通过单个文件,我的意思是即使hdf5_hl系统上不存在库,它也需要运行.优选的是,它也将运行,即使text,vector和/或containers缺失,而是因为这不是必需的reader-types,需要这些类型的反正.使用GHC API加载模块时,我希望它以已编译的形式加载,而不是运行解释.
我这样做的目的是希望自包含文件充当单个预编译的插件文件,稍后由不同的Haskell可执行文件加载和执行.其他插件可能根本不使用hdf5,并且它们保证使用的唯一包是reader-types,它实质上定义了插件接口类型.
我的系统上的HDF5库包含以下文件:libhdf5_la.la,libhdf5_hl.so,libhdf5.la,libhdf5.so,和类似的文件在文件名中的版本号.
我已经做了很多谷歌搜索,但我对所发现的所有边缘情况感到困惑.这里有一些例子,我确定不适合我的情况,或者我不知道.