Very general question about collaboration of C++/Mercury
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri May 8 20:23:40 AEST 1998
On 07-May-1998, Ulrich Mayring <u at 123.org> wrote:
> Hello there,
>
> first off, I'm a Prolog programmer and know next to nothing about Mercury.
> However, I read on the web-site that Mercury doesn't build executables,
> but generates C code.
Well, this is not strictly correct -- Mercury does of course build
executables, it is just that the way it does so involves first generating
C code.
The C code that Mercury generates is very low-level C code,
so the fact that it is C will not necessarily help you.
However, as it happens Mercury does have a good C interface, so
interfacing with C is quite feasible. C++ also has a very good C
interface, so it is possible to interface Mercury and C++ using the
two languages' C interfaces.
> This has given me an idea on whose feasibility I
> would ask you to comment:
>
> I am currently writing an application that on one hand has a rich and
> complex GUI, which should be very responsive and flexible as well. I am
> doing this part in Metrowerks CodeWarrior/PowerPlant, which is a C++
> framework for the Macintosh (which is my target platform).
>
> On the other hand at the bottom (or, if you will, at the top) of my app
> there exists data - not much now, but in the future there will be many
> types of various data that should be able to interact with each other
> intelligently. (Ultimately I might even want to have a visual modeller
> that generates that data, much like a 3D modeller that might generate
> OpenGL code or somesuch) Therefore I need to represent my data ideally in
> a declarative programming language, because that is just so much better
> than having some stupid C-style arrays and structs. On the other hand C
> compiles well and is fast. So, here's the scoop:
>
> Does it sound like a good idea to do my knowledge representation in
> Mercury, compile the code to C and integrate the C code in my C++ app?
This general scheme of writing the GUI in C++ and writing the
application logic in Mercury is very feasible, and indeed we have at
least one group of commercial users who are successfully using this
technique to produce Windows NT applications.
> To me two general questions arise (however, to you many more might):
>
> 1) Mercury-generated C ==> C++
> How do I interface between Mercury-generated C and my C++ application
> classes? Are there standardized accessor functions or something like that?
The Mercury-generated C is very low-level, so you don't want to
interface to it directly. However, you can get the Mercury compiler to
generate high-level C interfaces to Mercury procedures. Basically you
write some code in Mercury, and then export it to C using
:- pragma export(foo(in, out), "foo_in_out").
Here `foo(in, out)' is the name and mode of the Mercury predicate,
and "foo_in_out" is the name of the C function which will call it.
The Mercury compiler then automatically the code for foo_in_out()
and automatically generates a C header file containing a declaration for it.
You can #include that C header from your C++ code and call the function.
Conversely, you can write
:- pragma import(bar(in, out), "bar").
and then the Mercury predicate bar/2 will call the C function bar().
Note that bar() can actually be defined in C++, so long as you
define it with `extern "C"' to give it C linkage:
extern "C" void bar(...) { ... }
Mercury's `pragma export' and `pragma import' are similar to
C++'s `extern "C"' on definitions and declarations (respectively).
Sharing data between Mercury and C or C++ is not quite as easy as
sharing data between C and C++. Basically you define the
data structure in one language, and from the other language
you access it as an ADT using access procedures which are
imported or exported using `pragma import' or `pragma export'.
> 2) C++ ==> Mercury
> The user might want to change data by manipulating some GUI elements. I
> can of course write these changes to my C++ data structures, but how do I
> get it back to Mercury?
First you write some C code, or C++ code declared to have C linkage,
that manipulates these data structures. Then you can access that
code from within Mercury using `pragma import'.
OK, that was the good news. The bad news is that we have not yet
ported Mercury to the Mac. "Ah, but Mercury generates C code -- surely
the port should be trivial!" you say. Yes, the generated C code is
pretty portable, at least if you turn off the machine-specific optimizations
and gcc-specific optimizations. However, the Makefiles, shell scripts,
conservative garbage collector and other infrastructure are not so portable.
Actually the conservative garbage collector has already been ported to
the Mac, so I don't think that should be a problem. However, the
others would be. Are there ports of gcc, bash (or any other Bourne
shell), and GNU Make to the Mac? If so, then porting Mercury to the
Mac should not be difficult. If not, then it will definitely be a
non-trivial task.
Cheers,
Fergus.
P.S. I'd be happy to port Mercury to the Mac if someone donates
the Mac to do it on! ;-)
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the users
mailing list