2012-06-21 6 views
18

d. H. ist es möglich, Haskell-Code in eine C-Bibliothek einzubetten, sodass der Benutzer der Bibliothek nicht wissen muss, dass Haskell verwendet wird? Insbesondere, damit der Benutzer mehrere Bibliotheken, die Haskell einbetten, ohne Konflikte verwenden kann?Ist es möglich, Haskell in einer C-Bibliothek undurchsichtig einzubetten?

Soweit ich Dinge verstehe, betten Sie zwischen den Aufrufen von hs_init und hs_exit ein, aber diese beinhalten globale staatliche Shenanigans und sollten mit anderen Aufrufen in Konflikt geraten, nein?

Antwort

14

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).

+0

Ich weiß bereits, dass es möglich ist. Ich möchte wissen, ob es möglich ist _safely_. –

+0

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. –

+0

Es ist vollkommen akzeptabel und in einigen großen Systemen verwendet. –

Verwandte Themen