[mercury-users] C interface with main in C

Gustavo Ospina gos at info.ucl.ac.be
Fri Feb 22 01:01:54 AEDT 2002


I want to use the C interface to use Mercury exported predicates in a C module,
but conserving the main function in C.

For instance, I have this Mercury Module:

:- module export.

:- interface.

:- import_module int, io, list.

:- pred say_hello(io__state::di, io__state::uo) is det.

:- func math_calc(int, int) = int.

:- pred options(int, string).
:- mode options(in, in) is semidet.
:- mode options(in, out) is semidet.
:- mode options(out, in) is semidet.
:- mode options(out, out) is multi.

:- implementation.

say_my_name -->

math_calc(X, Y) = 3*X + 2*Y*Y.

options(N, S) :-
(	N = 1,
	S = "One"
	N = 2,
	S = "Two"
	N = 3,
	S = "Three"
	N = 4,
	S = "Four"
	N = 5,
	S = "Five"

% Exportation to C

:- pragma export(say_my_name(di, uo), "c_say_my_name").

:- pragma export(math_calc(in, in) = out, "c_math_calc").

:- pragma export(options(in, in), "c_options_1").
:- pragma export(options(in, out), "c_options_2").
:- pragma export(options(out, in), "c_options_3").

I want to use the predicates into the main function of a C program, like this:

#include "mercury_init.h"
#include "export.h"

#include <stdio.h>

int main(int argc, char **argv)
  int a, b, c;
  char str[10];
  char dummy;

  printf("This C program will call predicates exported by Mercury\n\n");

  /* Initialization of the Mercury Abstract Machine */
  mercury_init(argc, argv, &dummy);

  if (c_options_1(2, "Two"))
    printf("Test 1 successful: options(2, \"Two\") holds.\n");

  if (c_options_2(3, &str))
    printf("Test 2 successful: options(3, X) gives X = %s\n", str);
  a = 5;
  b = 8;

  c = c_math_calc(a, b);
    printf("Test 3 successful: math_calc(5, 8) = %d\n", c);

  /* Ending Mercury Abstract Machine */
  return mercury_terminate();

When I link just the two modules (with the one generated by c2init) the linker
says that there are an undefined reference to the predicate main/2. So, I've
tried to fix by writing a 'dummy' mercury module with an empty main predicat.
The linker generated the executable successfully but in the execution, nothing
is printed.

Other working solution is to make a mercury module which imports the C 'main'
function. But it's just what I don't want to do.

Is there an elegant way to fix the problem without extra Mercury modules?

Thanks for any help.

mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe

More information about the users mailing list