11

モジュールを動的にロードして実行しようとしていますが、

以下は私のコードです

TestModule.hs

module TestModule
        where

evaluate = "Hello !!!"

Invoke.hs

module Invoke
        where

import GHC
import DynFlags
import GHC.Paths (libdir)
import Unsafe.Coerce (unsafeCoerce)
import Data.Dynamic

execFnGhc :: String -> String -> Ghc a
execFnGhc modname fn = do
        mod <- findModule (mkModuleName modname) Nothing
        --setContext [IIModule mod]
        GHC.setContext [ GHC.IIDecl $ (GHC.simpleImportDecl . GHC.mkModuleName $ modname) {GHC.ideclQualified = True} ]
        value <- compileExpr (modname ++ "." ++ fn)
        let value' = (unsafeCoerce value) :: a
        return value'

Main2.hs

import GHC.Paths (libdir)
import GHC
import Invoke
--    import TestModule

main :: IO ()
main = runGhc (Just libdir) $ do
                        str <- execFnGhc "TestModule" "evaluate"
                        return str

プログラムを実行しようとすると、以下のエラーが表示されます

[root@vps mypproj]# ./Main2 
Main2: <command line>: module is not loaded: `TestModule' (./TestModule.hs)

何が欠けているのかわからない、誰かがこのエラーを解決するのを手伝ってくれる?

4

2 に答える 2

1

私の考えでは、問題はパスに関係しており、「TestModule」を読み込めない場合、プログラムは静かにエラーを出し、モジュールが読み込まれていないと不平を言います。すでにロードされているモジュールで execFnGhc を使用しようとしたことがありますか? また、Text.Parsec などの GHC に自然に存在するモジュールをロードして、その中で何かを実行しようとしたことがありますか?

私は自分自身をテストしたいのですが、GHC.Pathsライブラリがどこにもありません:/。

于 2013-04-08T03:57:33.390 に答える
0

私は最近、関連する GHC ソース コードを読んでいましたが、既にロードされていない限り、findModuleローカル モジュール (あなたの場合) では動作しないようです。TestModule.hs(ただし、リモート パッケージ内のモジュールでは機能します。)

addTargetコンパイル済みモジュールの GHCi スタイルの動的ロードを行うには、 andを使用するのが最善の策loadです。コメントで述べたように、セッションの動的フラグも初期化する必要があります。コードの作業バージョンは次のとおりです。

module Invoke
        where

import GHC
import DynFlags
import GHC.Paths (libdir)
import Unsafe.Coerce (unsafeCoerce)
import Data.Dynamic

execFnGhc :: String -> String -> Ghc String
execFnGhc modname fn = do
        dflags <- getDynFlags
        setSessionDynFlags dflags
        let target = Target (TargetModule (mkModuleName modname)) True Nothing
        addTarget target
        load (LoadUpTo (mkModuleName modname))
        mod <- findModule (mkModuleName modname) Nothing
        GHC.setContext [ GHC.IIDecl $ (GHC.simpleImportDecl . GHC.mkModuleName $ modname) {GHC.ideclQualified = True} ]
        value <- compileExpr (modname ++ "." ++ fn)
        let value' = (unsafeCoerce value) :: String
        return value'

のパラメータはTarget何ですか? 最初はモジュール名です。2 つ目は、オブジェクト コードのロードを許可するかどうか、または常にモジュールを解釈できるようにするかどうかです。最後はオプションの文字列バッファで、実際のファイルのソース コードをオーバーライドするために使用できます (これNothingは必要ないためです)。

どうやってこれを理解したのですか?GHC ソース コードでこれを実装するために GHCi が使用するコードと、compiler/main/GHC.hs. これは、GHC API で目的の処理を実行する方法を理解する最も信頼できる方法であることがわかりました。

混乱しますか?GHC API は、追加されたほどには設計されていませんでした...

于 2014-11-21T00:51:44.957 に答える