[英]Can't load a Haskell dll on Windows
我经常使用Haskell创建一些我在R中加载的DLL,这非常有效。
但是我有一些处理xlsx
库的代码,我可以将它编译成DLL而没有问题,但是当我在R中加载DLL时,这完全崩溃了R会话。 但是这只发生在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会话崩溃。 如果我删除test
功能,则没有这样的问题。 然而, test
功能甚至没有导出(使用foreign export
)并且它没有被其他函数调用,这不是很奇怪吗? 如果我不导出此函数,如果我不使用它,为什么DLL处理此函数?
更重要的是,当我加载DLL时R会话崩溃的原因,以及如何解决这个问题?
我现在有一个更小的例子。 这有效:
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有问题^?
。
使用此等效代码不会崩溃:
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
^? 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
,列出要导出的函数,例如funexport
和HsStart
,如下所示:
EXPORTS
funexport
HsStart
并在用于编译的命令行末尾添加MyDef.def
:
ghc -shared foo.hs StartEnd.c -o foo.dll MyDef.def
我刚刚测试了这个解决方案,它的工作原理。 然而,这是我第一次测试它,所以我不能保证。 我也很惊讶ghc
不会自动这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.