GHCi下的动态加载

18

我需要能够动态加载Haskell模块,并在动态加载的模块的上下文中评估表达式。

Hint可以做到这一点,问题是,在Windows下,它不能在GHCi下工作。

cygwin-bash> ghci HintTest.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: Main.
Prelude Main>
Prelude Main> main
[... lots of "Loading package" messages snipped]

GHCi runtime linker: fatal error: I found a duplicate definition for symbol
   _debugLn
whilst processing object file
   C:\PROGRAM FILES (X86)\HASKELL PLATFORM\2013.2.0.0\lib\ghc-prim-0.3.0.0\HSghc-prim-0.3.0.0.o
This could be caused by:
   * Loading two different object files which export the same symbol
   * Specifying the same object file twice on the GHCi command line
   * An incorrect `package.conf' entry, causing some object to be
     loaded twice.
GHCi cannot safely continue in this situation.  Exiting now.  Sorry.

当我直接使用GHC模块时,我得到了与“GHC /作为库”中展示的相同错误。

作为编译程序,HintTest可以正常运行。

有没有什么方法可以解决这个问题?

我不需要独立运行我的程序;始终使用GHCi就足够了。如果程序可以使用GHCi本身作为解释器而不是它自己的GHC副本,那将是很好的。也就是说,我想能够像这样做:

do
  context <- loadToGhci "MyModule.hs"
  inContext context "MyModule.myFunction 2 5"

当我返回到REPL时,MyModule 神奇地被加载到其中。context意味着它是一种携带GHCi状态的单子。

更新 相同的代码在Linux上也可以工作。也许这是GHC在Windows上的特定bug。有什么办法可以解决吗?

更新 2 这是完整的日志

Prelude Main> main
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Loading package Win32-2.3.0.0 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package old-locale-1.0.0.5 ... linking ... done.
Loading package time-1.4.0.1 ... linking ... done.
Loading package syb-0.4.0 ... linking ... done.
Loading package random-1.0.1.1 ... linking ... done.
Loading package filepath-1.3.0.1 ... linking ... done.
Loading package directory-1.2.0.1 ... linking ... done.
Loading package process-1.1.0.2 ... linking ... done.
Loading package pretty-1.1.1.0 ... linking ... done.
Loading package mtl-2.1.2 ... linking ... done.
Loading package containers-0.5.0.0 ... linking ... done.
Loading package hpc-0.6.0.0 ... linking ... done.
Loading package hoopl-3.9.0.0 ... linking ... done.
Loading package haskell-src-1.0.1.5 ... linking ... done.
Loading package old-time-1.1.0.1 ... linking ... done.
Loading package Cabal-1.16.0 ... linking ... done.
Loading package binary-0.5.1.1 ... linking ... done.
Loading package bin-package-db-0.0.0.0 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package ghc-7.6.3 ... linking ... done.
Loading package extensible-exceptions-0.1.1.4 ... linking ... done.
Loading package MonadCatchIO-mtl-0.3.0.5 ... linking ... done.
Loading package ghc-mtl-1.0.1.2 ... linking ... done.
Loading package ghc-paths-0.1.0.9 ... linking ... done.
Loading package utf8-string-0.3.7 ... linking ... done.
Loading package hint-0.3.3.7 ... linking ... done.


GHCi runtime linker: fatal error: I found a duplicate definition for symbol
   _debugLn
whilst processing object file
   C:\PROGRAM FILES (X86)\HASKELL PLATFORM\2013.2.0.0\lib\ghc-prim-0.3.0.0\HSghc-prim-0.3.0.0.o
This could be caused by:
   * Loading two different object files which export the same symbol
   * Specifying the same object file twice on the GHCi command line
   * An incorrect `package.conf' entry, causing some object to be
     loaded twice.
GHCi cannot safely continue in this situation.  Exiting now.  Sorry.

ghci和hint都使用ghc api。在Windows上同时使用两者可能会导致某些对象文件被重复加载。如果是这种情况,除非您想更改ghc api,否则实际上没有什么可以做的。 - Carl
1
@Carl 我刚在 Linux 上检查了相同的代码,它可以正常工作。也许这只是 Windows 特有的 bug? - n. m.
我不确定我是否正确理解了这个问题,但是这里提到动态库在Windows上并没有完全支持,并且有许多与动态链接相关的错误链接,其中一个可能是你的问题。 - gereeter
@gereeter 我认为没有涉及到动态库。该程序使用 GHCi 的加载器加载 .o 文件。 - n. m.
@n.m. 你能在你的帖子中包含“大量加载包”输出吗? - bennofs
显示剩余2条评论
1个回答

3
您正在尝试将字节码解释器和运行时动态加载到字节码解释器和运行时中。这是否有效取决于系统上底层C库的链接方式,这非常依赖于平台。
特别地,在链接时必须特别小心,否则C符号将会被复制,并且在第二次加载各种RTS模块时将导致链接器错误。

是的,这正是我想做的,而我想做这件事的原因是我已经有了字节码解释器和运行时(即 GHCi),但它不会将其功能暴露给在其下运行的程序。或者如果它确实这样做了,我不知道如何使用它。另一方面,该解释器具有非常好的命令行界面,我也想使用它。你知道实现我想要的另一种方法吗? - n. m.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接