Fwd: c2hs: E.g. #include <iostream> OK in *.cpp's, but not in *.h's

---------- Forwarded message ----------
From: Nick Rudnick
As far as I can tell from a quick look at hsqml, the stuff in Setup.hs isn't related to C2HS. What's more relevant is that hsqml defines a C library wrapper around the C++ library it uses -- C2HS is only used on that C wrapper, not on the C++ library itself. In general, C2HS doesn't support C++ at all, because it needs to be able to parse the header files that it includes and we use the C parser from the languagge-c package to do that. Any C++ constructs will just cause breakage. And your "old school" FFI definition doesn't look in any header files, which is why it has no trouble.
Basically, if you want to do something like what hsqml does, just take a look in the cbits directory there, in particular at hsqml.h which is the header that defines the C wrapper around the C++ library. This hsqml.h header is the one that's included in the C2HS files. If you want to wrap a C++ library directly, C2HS probably isn't the tool for the job. I know there was some work during the last GSOC on a C++ FFI wrapper, but I don't know if anything concrete came of it.
Cheers,
Ian.
On 6 April 2014 20:22, Nick Rudnick
wrote: Dear all,
maybe this is a piece of c2hs behaviour I missed to understand, but it appears happening with C++ style includes deep in the header call hierarchy – in case of a such backend C++ library, if one wishes to refer to by *.h's in c2hs (e.g. for access to types of it), one might have a problem.
- 8< cSample.h --------------------------------------------- #include <iostream> ///////// here, with c2hs, leading to build abort #ifdef __cplusplus extern "C" { #endif void sampleFunction(); #ifdef __cplusplus } #endif - 8< cSample.cpp --------------------------------------------- #include "cSample.h" #include <iostream> ///////// here no problem
void sampleFunction(){ std::cout << "OK" << std::endl; } - 8< ----------------------------------------------------------------
While 'old school' FFI (foreign import ccall) handles this effortlessly, c2hs uses to abort with an exception like C/cSample.h:3:20: fatal error: iostream: No such file or directory compilation terminated.
I see that hsqml gets around this, but apparently by tweaking Setup.hs in a way not quite trivial – would this be necessary in any case, or are there simpler alternatives?
Please excuse if I oversaw something, but I am afraid I didn't see this interesting issue covered elsewhere.
Thank you a lot in advance & cheers, Nick
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Ian Ross Tel: +43(0)6804451378 ian@skybluetrades.net www.skybluetrades.net

More or less. Basically, C2HS is *C* FFI tool only. If you get into a
situation where C2HS can see C++ header files, it's not going to work. How
you get around that is up to you. If your C++ library isn't too
complicated, a C wrapper as used in hsqml seems like a good choice, or you
can write the Haskell FFI import declarations yourself. If your C++
library is complicated and you really want to get at all of its public
interface, you could try using a real C++ FFI tool (the only one I've
really heard anything about is fficxx: http://ianwookim.org/fficxx/).
On 7 April 2014 15:33, Nick Rudnick
---------- Forwarded message ---------- From: Nick Rudnick
Date: 2014-04-07 15:28 GMT+02:00 Subject: Re: [Haskell-cafe] c2hs: E.g. #include <iostream> OK in *.cpp's, but not in *.h's To: Ian Ross Hi Ian,
thanks for clearing up :-)
So you mean the trick of hsqml primarily is
(A) dummy typedefs to char, e.g.:
typedef char HsQMLStringHandle;
(B) 'extern' sigantures, e.g.: extern void hsqml_init_string(HsQMLStringHandle*);
THIS WORKS...
Occasionally, one might use two headers, e.g. a *.hpp as actual C++ header neither listed in the *.cabal nor the *.chs, where instead it would be represented by a *.h, as described above.
No more...??
Thanks and cheers, Nick
2014-04-07 14:04 GMT+02:00 Ian Ross
: Hi Nick,
As far as I can tell from a quick look at hsqml, the stuff in Setup.hs isn't related to C2HS. What's more relevant is that hsqml defines a C library wrapper around the C++ library it uses -- C2HS is only used on that C wrapper, not on the C++ library itself. In general, C2HS doesn't support C++ at all, because it needs to be able to parse the header files that it includes and we use the C parser from the languagge-c package to do that. Any C++ constructs will just cause breakage. And your "old school" FFI definition doesn't look in any header files, which is why it has no trouble.
Basically, if you want to do something like what hsqml does, just take a look in the cbits directory there, in particular at hsqml.h which is the header that defines the C wrapper around the C++ library. This hsqml.h header is the one that's included in the C2HS files. If you want to wrap a C++ library directly, C2HS probably isn't the tool for the job. I know there was some work during the last GSOC on a C++ FFI wrapper, but I don't know if anything concrete came of it.
Cheers,
Ian.
On 6 April 2014 20:22, Nick Rudnick
wrote: Dear all,
maybe this is a piece of c2hs behaviour I missed to understand, but it appears happening with C++ style includes deep in the header call hierarchy - in case of a such backend C++ library, if one wishes to refer to by *.h's in c2hs (e.g. for access to types of it), one might have a problem.
- 8< cSample.h --------------------------------------------- #include <iostream> ///////// here, with c2hs, leading to build abort #ifdef __cplusplus extern "C" { #endif void sampleFunction(); #ifdef __cplusplus } #endif - 8< cSample.cpp --------------------------------------------- #include "cSample.h" #include <iostream> ///////// here no problem
void sampleFunction(){ std::cout << "OK" << std::endl; } - 8< ----------------------------------------------------------------
While 'old school' FFI (foreign import ccall) handles this effortlessly, c2hs uses to abort with an exception like C/cSample.h:3:20: fatal error: iostream: No such file or directory compilation terminated.
I see that hsqml gets around this, but apparently by tweaking Setup.hs in a way not quite trivial - would this be necessary in any case, or are there simpler alternatives?
Please excuse if I oversaw something, but I am afraid I didn't see this interesting issue covered elsewhere.
Thank you a lot in advance & cheers, Nick
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Ian Ross Tel: +43(0)6804451378 ian@skybluetrades.net www.skybluetrades.net
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Ian Ross Tel: +43(0)6804451378 ian@skybluetrades.net www.skybluetrades.net

Ian, thanks a lot :-)
In fact I have a quite elaborate C++ backend to deal with – so your
recommendation of fficxx is highly welcome... :-) :-) :-)
Cheers, Nick
BTW: For everybody trying out the way described before, please enclose
declarations by
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
in the *.hpp, too, to prevent an error.
2014-04-07 15:43 GMT+02:00 Ian Ross
More or less. Basically, C2HS is *C* FFI tool only. If you get into a situation where C2HS can see C++ header files, it's not going to work. How you get around that is up to you. If your C++ library isn't too complicated, a C wrapper as used in hsqml seems like a good choice, or you can write the Haskell FFI import declarations yourself. If your C++ library is complicated and you really want to get at all of its public interface, you could try using a real C++ FFI tool (the only one I've really heard anything about is fficxx: http://ianwookim.org/fficxx/).
On 7 April 2014 15:33, Nick Rudnick
wrote: ---------- Forwarded message ---------- From: Nick Rudnick
Date: 2014-04-07 15:28 GMT+02:00 Subject: Re: [Haskell-cafe] c2hs: E.g. #include <iostream> OK in *.cpp's, but not in *.h's To: Ian Ross Hi Ian,
thanks for clearing up :-)
So you mean the trick of hsqml primarily is
(A) dummy typedefs to char, e.g.:
typedef char HsQMLStringHandle;
(B) 'extern' sigantures, e.g.: extern void hsqml_init_string(HsQMLStringHandle*);
THIS WORKS...
Occasionally, one might use two headers, e.g. a *.hpp as actual C++ header neither listed in the *.cabal nor the *.chs, where instead it would be represented by a *.h, as described above.
No more...??
Thanks and cheers, Nick
2014-04-07 14:04 GMT+02:00 Ian Ross
: Hi Nick,
As far as I can tell from a quick look at hsqml, the stuff in Setup.hs isn't related to C2HS. What's more relevant is that hsqml defines a C library wrapper around the C++ library it uses -- C2HS is only used on that C wrapper, not on the C++ library itself. In general, C2HS doesn't support C++ at all, because it needs to be able to parse the header files that it includes and we use the C parser from the languagge-c package to do that. Any C++ constructs will just cause breakage. And your "old school" FFI definition doesn't look in any header files, which is why it has no trouble.
Basically, if you want to do something like what hsqml does, just take a look in the cbits directory there, in particular at hsqml.h which is the header that defines the C wrapper around the C++ library. This hsqml.h header is the one that's included in the C2HS files. If you want to wrap a C++ library directly, C2HS probably isn't the tool for the job. I know there was some work during the last GSOC on a C++ FFI wrapper, but I don't know if anything concrete came of it.
Cheers,
Ian.
On 6 April 2014 20:22, Nick Rudnick
wrote: Dear all,
maybe this is a piece of c2hs behaviour I missed to understand, but it appears happening with C++ style includes deep in the header call hierarchy – in case of a such backend C++ library, if one wishes to refer to by *.h's in c2hs (e.g. for access to types of it), one might have a problem.
- 8< cSample.h --------------------------------------------- #include <iostream> ///////// here, with c2hs, leading to build abort #ifdef __cplusplus extern "C" { #endif void sampleFunction(); #ifdef __cplusplus } #endif - 8< cSample.cpp --------------------------------------------- #include "cSample.h" #include <iostream> ///////// here no problem
void sampleFunction(){ std::cout << "OK" << std::endl; } - 8< ----------------------------------------------------------------
While 'old school' FFI (foreign import ccall) handles this effortlessly, c2hs uses to abort with an exception like C/cSample.h:3:20: fatal error: iostream: No such file or directory compilation terminated.
I see that hsqml gets around this, but apparently by tweaking Setup.hs in a way not quite trivial – would this be necessary in any case, or are there simpler alternatives?
Please excuse if I oversaw something, but I am afraid I didn't see this interesting issue covered elsewhere.
Thank you a lot in advance & cheers, Nick
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Ian Ross Tel: +43(0)6804451378 ian@skybluetrades.net www.skybluetrades.net
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Ian Ross Tel: +43(0)6804451378 ian@skybluetrades.net www.skybluetrades.net
participants (2)
-
Ian Ross
-
Nick Rudnick