Hi Wolfgang,
On Oct 12, 2007, at 15:22, Wolfgang Jeltsch wrote:
Hello,
what are good approaches for creating Haskell bindings to C++
libraries? The
most promising so far seems to create C wrappers around the C++
libraries and
then bind to them. Is it feasible to bind directly to C++ using
ccall by
relying on some standardized C++ ABI? What about H/Direct? Are
there any
other good ways?
Since the name mangling of C++ members, classes and functions are
compiler specific, I don't think there is a good way of directly
calling the C++ functions and methods. I wrapped all C++ methods of
my classes in C functions. I use the following structure:
C++ header file tvpi.hh:
#ifndef __TVPI_H
#define __TVPI_H
namespace Tvpi {
class Domain {
public:
Domain();
void joinWiden(Domain prev, mpz_class extrapolate);
};
#endif // __TVPI_H
==
C header file tvpi_c.h
#ifndef TVPI_C_H_
#define TVPI_C_H_
#ifdef __cplusplus
extern C {
#endif // __cplusplus
#undef TVPI_TYPE_DECLARATION
#define TVPI_TYPE_DECLARATION(Type) \
typedef struct Type ## _tag Type ## _t; \
typedef Type ## _t * Type ## _p; \
typedef Type ## _t const* const_ ## Type ## _p
TVPI_TYPE_DECLARATION(Domain);
Domain_p tvpiNew(void);
void tvpiFree(Domain_p d);
void tvpiJoin(Domain_p d1, Domain_p d2);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // TVPI_C_H_
==
C wrapper file, tvpi_c.cpp:
#include tvpi_c.h
#include tvpi.hh
using namespace Tvpi;
templateclass ToType, class FromType
const ToType* to_const(const FromType* x) {
return reinterpret_castconst ToType*(x);
}
templateclass ToType, class FromType
ToType* to_nonconst(FromType* x) {
return reinterpret_castToType*(x);
}
Domain_p tvpiNew() {
return to_nonconstDomain_t, Domain(new Domain());
}
void tvpiFree(Domain_p d) {
delete to_nonconstDomain, Domain_t(d);
}
Domain_p tvpiCopy(Domain_p d) {
return to_nonconstDomain_t, Domain
(new Domain(*to_constDomain, Domain_t(d)));
}
void tvpiJoin(Domain_p d1, Domain_p d2) {
mpz_class w(-1);
to_nonconstDomain, Domain_t(d2)-joinWiden(*to_nonconstDomain,
Domain_t(d1
), w);
}
==
I'm not claiming it's pretty, but it works on several g++ versions.
You also need to pass
something like -pgml g++ -optl -pg to ghc so it know that it should
link using g++ (and thereby linking against the C++ runtime).
Hope this helps,
Axel.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell