27

假设我有一个dictionary.txt文件,我需要将它读入地图并在我的程序中使用它,我怎样才能使这个 dictionary.txt 文件包含在编译的 exe 文件中?

4

4 回答 4

21

您必须想出自己的方法将其放入 Map,但http://hackage.haskell.org/package/file-embed会将其放入已编译的二进制文件中。我们使用它在我们的一些 Web 应用程序中嵌入模板。

于 2011-06-19T12:11:54.960 回答
15

您可以将序列化的数据类型存储为字节串文字。这是一个例子:

然而,文件嵌入使这个过程自动化,使得做非平凡的嵌入变得更容易。

所有方法本质上都归结为将静态数据表示为字节串文字,

{-# LANGUAGE OverloadedStrings #-}

import Data.Binary
import qualified Data.Map as M
import qualified Data.ByteString.Char8 as S
import Data.ByteString.Lazy
import Codec.Compression.GZip

--
-- this is a gzip compressed literal bytestring, storing a binary-encoded Data.Map
--
mytable =
    "\US\139\b\NUL\NUL\NUL\NUL\NUL\NUL\ETXEN\
    \\219\SO\194 \f\197\224\188\196\CAN\227\US\
    \\224\171~\NAKc\GS4ce\161`\178\191\215(\176\
    \\190\180\167\231\210\n\241\171\203\191\ti\
    \\157\217\149\249< \ENQ\214\&9>\202\162\179a\
    \\132X\233\ESC=\231\215\164\SYN\157\DC2D\226*\
    \\146\174o\t\167\DLE\209\"i_\240\193\129\199<W\
    \\250nC\CAN\212\CAN\162J\160\141C\178\133\216;\
    \\\@4\144-W\203\209x\205\140\166\RS\163\237]9f\
    \\170\143\ACK\163g\223\STX\184\&7\rH\222\FSW\
    \\130\&7D\197\NUL\164\&0U\193\186\t\186o\
    \\228\180~\NUL\a6\249\137#\SOH\NUL\NUL"

main = print =<< M.lookup "ghc" m
    where
        -- build the table from the bytestring:
        m :: M.Map String (Maybe String)
        m = decode . decompress . fromChunks . return $ mytable
于 2011-06-19T16:01:37.560 回答
8

您可以使用自定义Makefile/Setup.hs钩子并调用windres(如果您在 Windows 上)或objcopy/ elfrc(如果您在 Linux 上)将资源编译为 COFF/ELF 对象,然后您可以将其与 Haskell 对象文件结合以形成最终的可执行文件. 然后,您可以像这样使用 Haskell FFI 访问资源(未经测试):

-- We have an image resource called "_imgdata"
foreign import ccall "&" _imgdata :: CString 

-- Size of _imgdata is 405585 bytes.
imgdata :: CStringLen
imgdata = (_imgdata, 405585)

此解决方案将比使用文件嵌入(不进行CString->ByteString转换)更有效,但也更复杂。

顺便说一句,我在 cabal-install 工作期间最终还需要资源文件支持,因此它可能会集成到 Cabal 的某个未来版本中(如果我会实现它的话)。

于 2011-06-19T13:14:19.940 回答
7

我强烈建议在这里使用Template Haskell,加载文件并将其转换为 Haskell 数据类型。它不仅会被编译成最终的二进制文件,而且会被完全优化。

于 2011-06-19T16:02:27.210 回答