tweed at compsci.bristol.ac.uk
Wed Aug 29 06:52:01 EDT 2001
META: If one of the main Haskell lists is a better place for than ffi for
this discussion, please let me know.
Many thanks for the help Alastair. I'll study the Greencard and this code
this weekend and see if it looks like a good way to acheive what I'd like
to do. In the mean time, a couple of immediate points/questions.
On 28 Aug 2001, Alastair David Reid wrote:
> You might look at Greencard. Greencard was specifically designed to
> let you easily map a C function interface into the corresponding
> idiomatic Haskell type. I believe this was _not_ such an important
> goal for hdirect. [Other tools (which are being more actively
> developed) have the same goal - but I haven't used them so I can't
> comment on them.]
ATM I'm more interested in the opposite direction: getting informatoin out
of a Haskell function which returns a non-abstract, non-primitive data
> Although Greencard is targetted at C, we (the Yale group) used it with
> a C++ visual tracking library. I'm attaching some code to show you
> what it looks like because although 'extern "C"' does play a role,
> I think it's different from what you're thinking of.
> > Other than being inelegant, is there anything to
> > prevent me trying to hack on a stage in the foreign code interface
> > stuff that compares the output of `nm' and `nm --demangle' to do
> > automatic conversion into mangled-names when there is no overloading
> > going on. (I ask this because it would minimise the changes needed
> > to the C++ source code to call C++ functions.)
> I don't see a fundamental problem - but it does sound like one of
> those projects that is always 90% complete because the last 10% is too
> painful to do properly.
I'm a bit puzzled here: I've got an object file which, amongst other
things contains one function called blockMatchScore16x16Simple. It's
the only function of that name (no overloading). If I do the output nm
--demangle on the file the only occurrence of that string is in the
context of this line:
00000000 T blockMatchScore16x16Simple(int *, int, int, int, unsigned char
*, unsigned char *)
Equally the only occurence in the straight nm output is
00000000 T blockMatchScore16x16Simple__FPiiiiPUcT4
Doesn't this mean that to make the function calling mechanism work in one
of the Haskell ffi's `as is' all that has to be done is change the string
blockMatchScore16x16Simple into blockMatchScore16x16Simple__FPiiiiPUcT4.
(I suppose a C++ compiler might theoretically be allowed to have a
completely different calling convention to the corresponding C one, but I
can't imagine it actually happening in practice.) Note that I'm not
proposing to do anything for either overloaded or `optional argument'
functions, it'd just be nice to be able to avoid a ripple effect when,
after changing a function to be extern "C" so that it can be called from
Haskell any object file containing a call to that function has to be
recompiled. And then recompiled again when I finish the prototyping and
take away the extern "C" (Cf. my .signature :-) ).
> 5) The system this was used in was described in our ICSE'99 paper:
Yes it was reading this paper recently which prompted me to think again
about trying to integrate Haskell prototyping with the C++ code. However,
that paper seems to tackle the problem of building applications (more
especially the control logic) from well understood and implemented
low-level, compute-intensive primitives in C++. I'm thinking more about
the situation where you're actively researching new low-level primitives
and it'd be nice to be able to try out ideas for new low-level stuff
quickly in haskell.
A good example which has happened recently is formulating an objective
function over a long vector which the plan is to minimise by `annealing'
using the partial derivatives; many times the definition may have multiple
local minima which prevent convergence to the `correct' answer, and this
property is often quite sensitive to the exact form of the objective
function. It'd be nice to be able to experiment with this in a language
with garbage collection, local lambda functions, list comprehensions, etc.
However, if the algorithm looks promising it'll be translated into the C++
part of the program for quickest execution. By contrast, the
control-logic parts of my programs are relatively simple.
To be more concrete what I'd like to be able to do without too much work
setting up each new case is
C++ ----------> Haskell
C++ function <------
(The re-entrant call into C++ is for simple calls to simple numerical
functions, say gaussian_err(float *mean,float **covar,float *x) which
could be defined in Haskell without any problems but I'd just like to
minimise the duplication because each duplication allows the possibilities
of typos.) Whilst the C++ side does have all the weird (and wonderful
aspects) of C++ like objects, overloading, etc, I don't see that it'd be
particularly useful for what I want to get done to move them to across the
language border; i.e., I'm basically thinking about interfacing to C
functions, except compiled with a C++ compiler.
Many thanks for any illumination anyone can shed on this,
www.cs.bris.ac.uk/~tweed/pi.htm |tweed's law: however many computers
email: tweed at cs.bris.ac.uk | you have, half your time is spent
work tel: (0117) 954-5250 | waiting for compilations to finish.
More information about the FFI