我經常創建一些帶有加載到R中的Haskell的DLL,這很好。無法在Windows上加載Haskell dll
但我有一些與xlsx
庫有關的代碼,我可以將它編譯成一個沒有問題的DLL,但是當我在R中加載DLL時,這會完全崩潰R會話。然而,這隻發生在Windows上,在Linux上沒有問題。
我設法找到一個最小的例子,有一些奇怪的。這是我的小例子:如果我編譯這段代碼的DLL,裝載在讀該DLL崩潰在Windows R對話
{-# 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 ...
。如果我刪除test
函數,則不存在這樣的問題。然而test
函數甚至沒有被導出(使用foreign export
),並且它不被其他函數調用,是不是很奇怪?如果我不導出這個函數,並且如果我不使用它,爲什麼DLL處理這個函數?
更重要的是,爲什麼R會話在我加載DLL時崩潰,以及如何解決這個問題?
編輯
我現在有一個更小例子。這工作:
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
問題。現在讓我試試我的真實例子...
不是一個Haskell用戶,但這看起來很瘋狂的行爲。這也看起來相關:https://ghc.haskell.org/trac/ghc/ticket/5987 –
是的,這很奇怪。最後,使用'MyDef.def',我只有兩個導出的符號,並且該DLL可以工作。我想知道爲什麼GHC出口> 65535無用的符號。 –
這並不奇怪,如果你想一想。函數應用程序在GHC中的工作方式意味着它需要一個信息表和一個關於它實現的每個函數的閉包。這意味着,如果你有一個Haskell dll引用另一個Haskell dll(例如當GHC和cabal使用動態方式),我們需要信息和閉包可用。也許一個標誌,表明該DLL不會被用作導入將是有益的,我會添加一個筆記。然而,什麼是錯誤是我們重新導出從其他包導入的功能。我會考慮修復GHC 8.4。 – Phyx