简体   繁体   English

无法在Windows上加载Haskell dll

[英]Can't load a Haskell dll on Windows

I often create some DLLs with Haskell that I load in R, and this works very well. 我经常使用Haskell创建一些我在R中加载的DLL,这非常有效。

But I have some code dealing with the xlsx library, I can compile it to a DLL without issue, but when I load the DLL in R, this totally crashes the R session. 但是我有一些处理xlsx库的代码,我可以将它编译成DLL而没有问题,但是当我在R中加载DLL时,这完全崩溃了R会话。 However this occurs on Windows only, there's no issue on Linux. 但是这只发生在Windows上,Linux上没有问题。

I managed to find a minimal example and there's something weird. 我设法找到一个最小的例子,有一些奇怪的东西。 This is my minimal example: 这是我的最小例子:

{-# 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 ...

If I compile this code to a DLL, loading this DLL in R crashes the R session on Windows. 如果我将此代码编译为DLL,则在R中加载此DLL会导致Windows上的R会话崩溃。 There's no such issue if I remove the test function. 如果我删除test功能,则没有这样的问题。 However the test function is not even exported (with foreign export ) and it is not called by the other functions, isn't it weird ? 然而, test功能甚至没有导出(使用foreign export )并且它没有被其他函数调用,这不是很奇怪吗? If I don't export this function and if I don't use it, why the DLL deals with this function ? 如果我不导出此函数,如果我不使用它,为什么DLL处理此函数?

And more importantly, why the R session crashes when I load the DLL, and how to fix that ? 更重要的是,当我加载DLL时R会话崩溃的原因,以及如何解决这个问题?

Edit 编辑

I have a more minimal example now. 我现在有一个更小的例子。 This works: 这有效:

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

And this crashes: 这崩溃了:

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

It looks like Windows has a problem with ^? 看起来Windows有问题^? .

Edit 2 编辑2

No crash with this equivalent code: 使用此等效代码不会崩溃:

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 has a problem with ^? ixSheet Windows有问题^? ixSheet ^? ixSheet . ^? ixSheet Now let me try on my real example... 现在让我试试我的真实例子......

I don't have a solution ( edit: I have one, see below ) but I can say this is due to the limit of number of exported symbols. 我没有解决方案( 编辑:我有一个,见下文 ),但我可以说这是由于导出符号数量的限制。

When I compile the code 当我编译代码

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

and I inspect the DLL with DependencyWalker , I see there are 48318 exported symbols. 我用DependencyWalker检查DLL,我看到有48318个导出的符号。 That's acceptable. 这是可以接受的。

But for the other code: 但对于其他代码:

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

the generated DLL reaches the maximal number of exported symbols: there are 65535=2^16-1 exported symbols. 生成的DLL达到导出符号的最大数量:有65535 = 2 ^ 16-1个导出符号。 This DLL is "truncated". 此DLL被“截断”。

Edit: A possible solution ! 编辑:可能的解决方案!

A possible solution consists in using a def file. 可能的解决方案包括使用def文件。 In a file MyDef.def , list the functions you want to export, eg funexport and HsStart , like this: 在文件MyDef.def ,列出要导出的函数,例如funexportHsStart ,如下所示:

EXPORTS
 funexport
 HsStart

and add MyDef.def at the end of the command line you use to compile: 并在用于编译的命令行末尾添加MyDef.def

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

I have just tested this solution and it works. 我刚刚测试了这个解决方案,它的工作原理。 However this is the first time I test it, so I would not guarantee yet. 然而,这是我第一次测试它,所以我不能保证。 I'm also surprised that ghc does not automatically do that. 我也很惊讶ghc不会自动这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM