Get out structured data from a C/C++ library in Haskell

Hello everybody. I'm new to the list so I'd like to say hello to you. I'm a student of computer science and early practitioner of Haskell. I've decided to implement the next project in Haskell but I need to interface a C++ library. I've read all the wikis material about the matter and I have an understanding of how FFI to C works in general. The library in question is a SAT solver for LTL formulas, and all I need to do is to be able to create the AST of the formula (Haskell will do the parsing) and pass it to the library, and then get back the reply. From the C++ point of view, the AST of the formulas consists simply of objects linked together with raw pointers. Nodes are of the same type, with an internal enum that specifies the type of node, so it's not an inheritance hierarchy or fancy things... What I would like to do is to be able to declare an algebraic data type that represents the AST and somehow mangle it to a form that can be passed to the C++ function of the library (that I can wrap into an extern "C" function to be able to use it through FFI if needed). How can I do that? In general, I've only seen example of how to exchange primitive types with C functions through the FFI, but not for example structures or pointers to structures. Note that I have control over the source code of the C++ library too, so the question includes suggestions about how to structure the C++ data as well, to ease the integration. Thank you for your help, Nicola

if you want to see a REALLY nice example of mapping (back and forth!)
between a C++ AST and an Haskell AST, llvm-general is a pretty good role
model
http://hackage.haskell.org/package/llvm-general
On Fri, Aug 8, 2014 at 10:34 AM, Nicola Gigante
Hello everybody.
I'm new to the list so I'd like to say hello to you. I'm a student of computer science and early practitioner of Haskell.
I've decided to implement the next project in Haskell but I need to interface a C++ library. I've read all the wikis material about the matter and I have an understanding of how FFI to C works in general.
The library in question is a SAT solver for LTL formulas, and all I need to do is to be able to create the AST of the formula (Haskell will do the parsing) and pass it to the library, and then get back the reply.
From the C++ point of view, the AST of the formulas consists simply of objects linked together with raw pointers. Nodes are of the same type, with an internal enum that specifies the type of node, so it's not an inheritance hierarchy or fancy things... What I would like to do is to be able to declare an algebraic data type that represents the AST and somehow mangle it to a form that can be passed to the C++ function of the library (that I can wrap into an extern "C" function to be able to use it through FFI if needed).
How can I do that? In general, I've only seen example of how to exchange primitive types with C functions through the FFI, but not for example structures or pointers to structures.
Note that I have control over the source code of the C++ library too, so the question includes suggestions about how to structure the C++ data as well, to ease the integration.
Thank you for your help, Nicola _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Il giorno 08/ago/2014, alle ore 16:53, Carter Schonwald
if you want to see a REALLY nice example of mapping (back and forth!) between a C++ AST and an Haskell AST, llvm-general is a pretty good role model http://hackage.haskell.org/package/llvm-general
Thank you very much! The source code is quite complex, given the complexities of the LLVM IR. Any pointer to understand what's going on? Thank you, Nicola

How can I do that? In general, I've only seen example of how to exchange primitive types with C functions through the FFI, but not for example structures or pointers to structures.
Foreign.Storable is the key to packing and unpacking a struct. The hsc2hs utility adds some support for struct member names, which will make your code more convenient and robust. You will also find "peek" and "poke" functions in Foreign.Storable, for pointer access. Donn

Il giorno 08/ago/2014, alle ore 17:29, Donn Cave
How can I do that? In general, I've only seen example of how to exchange primitive types with C functions through the FFI, but not for example structures or pointers to structures.
Foreign.Storable is the key to packing and unpacking a struct. The hsc2hs utility adds some support for struct member names, which will make your code more convenient and robust. You will also find "peek" and "poke" functions in Foreign.Storable, for pointer access.
Thanks! Is this the approach used by the llvm-general library? Moreover, I see that peek and poke return IO a, so I can't pretend that the interface that I'm wrapping is pure, can I? Nicola

On Fri, Aug 8, 2014 at 7:51 PM, Nicola Gigante
Moreover, I see that peek and poke return IO a, so I can't pretend that the interface that I'm wrapping is pure, can I?
I believe that providing a pure interface to FFI functions was in fact the reason unsafePerformIO was introduced. So if you know the function you're wrapping is in fact pure, you can use it to provide a pure Haskell interface to it. Erik

yup! But first write it correctly then make it pretty :)
On Fri, Aug 8, 2014 at 2:45 PM, Erik Hesselink
On Fri, Aug 8, 2014 at 7:51 PM, Nicola Gigante
wrote: Moreover, I see that peek and poke return IO a, so I can't pretend that the interface that I'm wrapping is pure, can I?
I believe that providing a pure interface to FFI functions was in fact the reason unsafePerformIO was introduced. So if you know the function you're wrapping is in fact pure, you can use it to provide a pure Haskell interface to it.
Erik _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Il giorno 08/ago/2014, alle ore 20:45, Erik Hesselink
On Fri, Aug 8, 2014 at 7:51 PM, Nicola Gigante
wrote: Moreover, I see that peek and poke return IO a, so I can't pretend that the interface that I'm wrapping is pure, can I?
I believe that providing a pure interface to FFI functions was in fact the reason unsafePerformIO was introduced. So if you know the function you're wrapping is in fact pure, you can use it to provide a pure Haskell interface to it.
Yes it makes sense, thank you :)
Erik
Nicola

Nicola Gigante
Il giorno 08/ago/2014, alle ore 17:29, Donn Cave
ha scritto: Foreign.Storable is the key to packing and unpacking a struct. The hsc2hs utility adds some support for struct member names, which will make your code more convenient and robust. You will also find "peek" and "poke" functions in Foreign.Storable, for pointer access.
...
Moreover, I see that peek and poke return IO a, so I can't pretend that the interface that I'm wrapping is pure, can I?
Funny you should ask ... I just happened to notice something about pretending an external function is pure, in the library documentation for Foreign.Marshall.unsafeLocalState. I can't say for sure whether it would serve your purpose here or not - the documentation could be read to say it does, anyway, and the function signature is IO a -> a. I meant to say, about hsc2hs, documentation can be found in the GHC user manual, chapter 12 or thereabouts. Donn
participants (4)
-
Carter Schonwald
-
Donn Cave
-
Erik Hesselink
-
Nicola Gigante