Ja, es ist possible Haskell-Code von C (und umgekehrt) über FFI, die Foreign Function Interface aufrufen. Leider, wie die haskell.org docs sagt, kann man nicht die Anrufe vermeiden, um die Haskell-Umgebung zu initialisieren und finalisieren:
Der Aufruf von hs_init() initialisiert Laufzeitsystem des GHC. Versuchen Sie nicht, rufen Sie alle Haskell-Funktionen aufrufen vor dem Aufruf von hs_init(): schlimme Dinge werden zweifellos passieren.
Aber this ist interessant auch:
Es können mehrere Anrufe hs_init(), aber jeder sollte durch eine (und nur eine) abgestimmt sein Aufruf hs_exit()
Und furthermore:
die FFI spec erfordert die Implementierung Unterstützung für die Neuinitialisierung selbst nach dem Herunterfahren mit hs_exit(), aber GHC nicht unterstützt derzeit das.
Grundsätzlich meine Idee ist, dass Sie diese Daten nutzen, um möglicherweise youself einen Wrapper C++ Klasse zu schreiben, die von hs_init
und hs_exit
unter Verwendung Vorlage Methoden umgeben, die Anrufe zu hs_init
und hs_exit
für Sie, in Beispiel verwaltet, die Sie Überschreiben Sie mithilfe eines beliebigen Haskell-Aufrufs. Beachten Sie jedoch die Interaktionen mit anderen Bibliotheken, die haskell code aufrufen: geschachtelte Schichten von Aufrufen zu hs_init
und hs_exit
sollten OK sein (es ist also sicher, Bibliotheken zu verwenden, die sie zwischen Ihren Wrappern aufrufen), aber die Gesamtzahl der Aufrufe sollte immer übereinstimmen. Das heißt, wenn diese Bibliotheken die Umgebung nur initialisieren, ohne zu versuchen, sie zu schließen, liegt es an Ihnen, den Job zu beenden.
Weitere (wahrscheinlich besser) Idee, ohne Vererbung und vorrangige Nutzung, kann eine einfache Klasse haben HaskellEnv
die hs_init
im Konstruktor und hs_exit
im Destruktor aufruft. Wenn Sie diese als automatische Variablen deklarieren, erhalten Sie, dass die Aufrufe an hs_init
und hs_exit
immer übereinstimmen, und der letzte Aufruf an hs_exit
wird vorgenommen, sobald das letzte HaskellEnv
Objekt zerstört wird, wenn Sie den Bereich verlassen. Werfen Sie einen Blick auf this question, um die Erstellung von Objekten auf dem Heap zu verhindern (sie können in diesem Fall gefährlich sein).
Ich weiß bereits, dass es möglich ist. Ich möchte wissen, ob es möglich ist _safely_. –
Sie müssen nur vorsichtig sein beim Aufruf von 'hs_init' und' hs_exit', denke ich.Sie können versuchen, sich in C++ - Klassen zu verpacken, um diese Aufrufe auf sichere Weise zu verpacken, aber es liegt an Ihnen. Der erste Weg, der mir in den Sinn kommt, ist die Verwendung von Template-Methoden, die von 'hs_init' und' hs_exit' umgeben sind und die Sie mit einem beliebigen Haskell-Aufruf überschreiben können. –
Es ist vollkommen akzeptabel und in einigen großen Systemen verwendet. –