2013-05-29 18 views
11

Próbuję dynamicznie kompilować i ładować moduły Haskell za pomocą interfejsu API GHC. Rozumiem, że interfejs API różni się w zależności od wersji, więc mówię konkretnie o GHC 7.6. *.Dynamiczne ładowanie skompilowanego modułu Haskell - GHC 7.6

Próbowałem uruchomić ten sam kod na MacOS i Linux. W obu przypadkach moduł Plugin kompiluje się poprawnie, ale podaje następujący błąd: Cannot add module Plugin to context: not interpreted

Problem jest podobny do tego w this, gdzie moduł zostałby załadowany tylko wtedy, gdy został skompilowany w tym samym przebiegu programu hosta.

-- Host.hs: compile with ghc-7.6.* 
-- $ ghc -package ghc -package ghc-paths Host.hs 
-- Needs Plugin.hs in the same directory. 
module Main where 

import GHC 
import GHC.Paths (libdir) 
import DynFlags 
import Unsafe.Coerce 

main :: IO() 
main = 
    defaultErrorHandler defaultFatalMessager defaultFlushOut $ do 
     result <- runGhc (Just libdir) $ do 
     dflags <- getSessionDynFlags 
     setSessionDynFlags dflags 
     target <- guessTarget "Plugin.hs" Nothing 
     setTargets [target] 
     r <- load LoadAllTargets 
     case r of 
      Failed -> error "Compilation failed" 
      Succeeded -> do 
      setContext [IIModule (mkModuleName "Plugin")] 
      result <- compileExpr ("Plugin.getInt") 
      let result' = unsafeCoerce result :: Int 
      return result' 
     print result 

A plugin:

-- Plugin.hs 
module Plugin where 

getInt :: Int 
getInt = 33 

Odpowiedz

14

Problem polega na tym, że używasz IIModule. Oznacza to, że chcesz wprowadzić moduł i wszystko w nim zawarte, w tym elementy nie wyeksportowane do kontekstu. Jest w zasadzie taki sam jak :load z gwiazdką w GHCi. I jak już zauważyliście, działa to tylko z zinterpretowanym kodem, ponieważ pozwala wam "zajrzeć do środka" modułu.

Ale to nie jest to, czego potrzebujesz tutaj. To, czego potrzebujesz, to załadowanie go tak, jakbyś użył :module lub deklaracji import, która działa z skompilowanymi modułami. W tym celu użyjesz IIDecl, która przyjmuje deklarację importową, którą możesz wykonać pod numerem simpleImportDecl:

setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")] 
Powiązane problemy