gpt4 book ai didi

r - 无法在 Windows 上加载 Haskell dll

转载 作者:行者123 更新时间:2023-12-02 03:00:25 24 4
gpt4 key购买 nike

我经常用 Haskell 创建一些 DLL,然后加载到 R 中,效果非常好。

但我有一些处理xlsx 库的代码,我可以毫无问题地将它编译成 DLL,但是当我在 R 中加载 DLL 时,这完全导致 R session 崩溃。然而,这仅发生在 Windows 上,在 Linux 上没有问题。

我设法找到了一个最小的例子,但有些东西很奇怪。这是我的最小示例:

{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE OverloadedStrings #-}

module TestDLL where
import Codec.Xlsx
import Control.Lens
import qualified Data.ByteString.Lazy as L
import Foreign
import Foreign.C
import Foreign.C.String (peekCString, newCString)

test :: IO ()
test = do
bs <- L.readFile "report.xlsx"
let value = toXlsx bs ^? ixSheet "List1" .
ixCell (3,2) . cellValue . _Just
putStrLn $ "Cell B3 contains " ++ show value

... some elementary functions here ...

如果我将此代码编译为 DLL,则在 R 中加载此 DLL 会使 Windows 上的 R session 崩溃。如果我删除 test 函数,就不会有这样的问题。然而 test 函数甚至没有被导出(使用 foreign export)并且它没有被其他函数调用,这不是很奇怪吗?如果我不导出此函数并且不使用它,为什么 DLL 会处理此函数?

更重要的是,为什么在我加载 DLL 时 R session 会崩溃,以及如何解决这个问题?

编辑

我现在有一个更简单的例子。这有效:

test :: IO Xlsx
test = do
bs <- L.readFile "report.xlsx"
return $ toXlsx bs

这会崩溃:

test :: IO (Maybe Worksheet)
test = do
bs <- L.readFile "report.xlsx"
return $ toXlsx bs ^? ixSheet "List1"

看起来 Windows 的 ^? 有问题。

编辑2

这个等效代码没有崩溃:

test :: IO (Maybe Worksheet)
test = do
bs <- L.readFile "report.xlsx"
let xlsx = toXlsx bs
let sheets = _xlSheets xlsx
let mapping = DM.fromList sheets
return $ DM.lookup "List1" mapping

Windows 有问题^? ixSheet。现在让我试试我的真实例子......

最佳答案

我没有解决方案(编辑:我有一个,见下文)但我可以说这是由于导出符号数量的限制。

当我编译代码时

test :: IO (Maybe Worksheet)
test = do
bs <- L.readFile "report.xlsx"
let xlsx = toXlsx bs
let sheets = _xlSheets xlsx
let mapping = DM.fromList sheets
return $ DM.lookup "List1" mapping

然后我用 DependencyWalker 检查 DLL ,我看到有 48318 个导出符号。这是可以接受的。

但是对于其他代码:

test :: IO (Maybe Worksheet)
test = do
bs <- L.readFile "report.xlsx"
return $ toXlsx bs ^? ixSheet "List1"

生成的DLL达到最大导出符号数:导出符号数为65535=2^16-1。此 DLL 被“截断”。

编辑:一个可能的解决方案!

一个可能的解决方案是使用def 文件。在文件 MyDef.def 中,列出您要导出的函数,例如funexportHsStart,像这样:

EXPORTS
funexport
HsStart

并在用于编译的命令行末尾添加MyDef.def:

ghc -shared foo.hs StartEnd.c -o foo.dll MyDef.def

我刚刚测试了这个解决方案并且它有效。然而这是我第一次测试它,所以我还不能保证。我也很惊讶 ghc 不会自动执行此操作。

关于r - 无法在 Windows 上加载 Haskell dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46448892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com