2012-06-05 7 views
10

Natürlich ist die Antwort, irgendwie einen zusammenhängenden Speicherblock zu übergeben/aufzunehmen, also ist die Frage mehr, wie man das macht. Für den Moment könnte ich das Problem noch vermeiden, indem ich Wrapper-Funktionen auf der C-Seite schreibe, aber das ist keine große Dauerlösung.Haskell FFI - Wie mit C-Funktionen, die akzeptieren oder zurückgeben Strukturen anstelle von Zeigern auf Strukturen?

+0

Suchen Sie etwas wie [dies] (http://www.haskell.org/haskellwiki/FFICookBook#Working_with_structs). –

+0

Nur zur Bestätigung: Sie wollen die Struktur nach Wert übergeben, nicht Referenz? –

+0

@Don ja, das ist richtig. – Cubic

Antwort

12

Das FFI unterstützt keine beliebigen Haskell-Typen, die nach Wert übergeben werden können.

Sie können nur Werte vom Typ passieren (und einige davon sind Zeiger):

Int#, Word#, 
Char#, 
Float#, Double#, 
Addr#, 
StablePtr# a, MutableByteArray#, ForeignObj#, and ByteArray#. 

, also eine Struktur zu übergeben Sie den Anruf über einen C-Wrapper wickeln müssen; Das nimmt einen Zeiger und übergibt seinen Wert an die C-Funktion, die Sie tatsächlich aufrufen möchten.

Eine aktuelle GHC-Erweiterung ermöglicht "primop" -Importe - die den FFI-Mechanismus umgehen und willkürliche Aufrufkonventionen und das Übergeben von Strukturen über ungepackte Tupel unterstützen. Z.B.

foreign import prim "ITCHv41_run" 
    parseITCHv41# :: Addr# -> Word# 
       -> (# Int#, Word#, Word#, Word#, Word#, Word# #) 

Sie können diese verwenden, tricky low level stuff so zu tun.

+3

Danke für die Verknüpfung dieses Blogs - es hat eine Menge wirklich nützlicher Sachen. – Crashworks