[comp.lang.fortran] f77 and C++ w/ cin/cout: can it be done?

ccea3@rivm.UUCP (Adri Verhoef) (11/10/88)

- I have this fortran-file "m.f":
      program main
      call hello()
      end

- and I have this C++-file "s.c":
#include <stream.h>
void hello_()
{
	STATEMENTS;
}

- I compile "m.f":
$ f77 -c m.f

- Then I compile "s.c", and execute a.out:

- The first time, I replace STATEMENTS by:
	printf("Hello, %s\n", "world");
$ CC -c s.c
$ f77 m.o s.o -lC
$ a.out
Hello, world

	- The second time, I replace STATEMENTS by:
		cout << "Hello, world\n";
	$ CC -c s.c
	$ f77 m.o s.o -lC
	$ a.out
	Bus error - core dumped
	$ adb
	$c
	__ostream__lshiftFPC__(14598,11ff1)
	_hello_()
	_MAIN__()
	_main(1,7fffef30,7fffef38)

- The third time, I replace STATEMENTS by:
	char str[128];  cin >> str;
$ CC -c s.c
$ f77 m.o s.o -lC
$ a.out
Memory fault - core dumped
$ adb
$c
__istream__rshiftFPC__(13320,7fffee5c)
_hello_()
_MAIN__()
_main(1,7fffef30,7fffef38)

- At this point, I got behold of the "s..c"-file.
- The following line was contained in the "s..c"-file:
_istream__rshiftFPC__ ( & cin , _auto_str ) ;

- I don't know what the trouble could be.  Maybe the f77-compiler?

mjs@cbnews.ATT.COM (martin.j.shannon) (11/10/88)

In article <1118@rivm05.UUCP> ccea3@rivm05.UUCP (Adri Verhoef) writes:
>- I have this fortran-file "m.f":
>      program main
>      call hello()
>      end
>- and I have this C++-file "s.c":
>#include <stream.h>
>void hello_()
>{
>	STATEMENTS;
>}
>- The first time, I replace STATEMENTS by:
>	printf("Hello, %s\n", "world");
>$ a.out
>Hello, world

This works because there are no static constructors involved, so it doesn't
matter which compiler generates main.

>- The second time, I replace STATEMENTS by:
>	cout << "Hello, world\n";
>$ a.out
>Bus error - core dumped

Since the static constructor for cout was never invoked, there is no
initialiaztion performed for the stream, and the constents of the class are
garbage.

>- The third time, I replace STATEMENTS by:
>	char str[128];  cin >> str;
>$ a.out
>Memory fault - core dumped

Since the static constructor for cin was never invoked, there is no
initialiaztion performed for the stream, and the constents of the class are
garbage.

In general:
Cfront recognizes that main is the 1st executable statement in a source file,
and appropriately replaces the user's main with code that arranges to make sure
that static constructors are called.  Thus, when mixing languages (not a
particularly safe thing to do; though possible in many systems), the executable
code generated for main must come from cfront.

l
i
n
e

c
o
u
n
t
e
r

f
o
o
d
.
-- 
Marty Shannon; AT&T Bell Labs; Liberty Corner, NJ
(Affiliation given for identification only.)

newsuser@LTH.Se (LTH network news server) (11/11/88)

In article <1118@rivm05.UUCP> ccea3@rivm05.UUCP (Adri Verhoef) writes:
>- I have this fortran-file "m.f":
>      program main
>      call hello()
>      end
>
>- and I have this C++-file "s.c":
>#include <stream.h>
>void hello_()
>{
>	STATEMENTS;
>}

I have successfully mixed FORTRAN and C++ code.  The problem was:

	1.  The FORTRAN run-time system (including i/o) must
	    be initialized in some way unknown to me.

	2.  Static constructors must be called in C++ before
	    any of my code.

The solution, which may be peculiar to our Silicon Graphics IRIS, is:

	1.  My FORTRAN ``main'' program calls a C initialization
	    function (reason is exaplained in 2.):

		PROGRAM MAIN
		CALL CINIT()
		...
		END

	2.  The purpose of the C function is to call the C++ initialization
	    function _main(), which is supplied by the compiler.  My
	    FORTRAN can't call a subroutine beginning in ``_''.

		void cinit()
		{
		    _main();
		}

I have written no FORTRAN in my application, but I do use a major run-time
library written i FORTRAN.  The approach above works in my particular
application, but I cannot guarantee it will help you.

I you *have* to use FORTRAN, good luck -- may the force be with you.

Dag Bruck
-- 
Department of Automatic Control		Internet:  dag@control.lth.se
Lund Institute of Technology
P. O. Box 118				Phone:	+46 46-108779
S-221 00 Lund, SWEDEN			Fax:    +46 46-138118

ccea3@rivm.UUCP (Adri Verhoef) (11/12/88)

Thanks, world!
I put an example in a possible solution:
>- I have this fortran-file "m.f":
       subroutine f
       call hello()
       end

>- and I have this C++-file "s.c":
>#include <stream.h>
 main()
 {
 	extern void f_();
 
 	f_();
 }
>void hello_()
>{
>	STATEMENTS;
>}

>- I compile "m.f":
>$ f77 -c m.f
>
>- I replace STATEMENTS by:
 	char str[256];
 	printf("__printf__Hello, %s\n", "world");
 	cout << " __cout__ Type your name: ";
 	cin >> str;
 	cout << " __cout__ Hello, " << str << ".\n";
>- Then I compile "s.c", and execute a.out:
 $ CC s.c m.o -lF77 -lI77
>$ a.out
 __printf__Hello, world
  __cout__ Type your name: a3
  __cout__ Hello, a3.

And everything runs as expected (namely OK).
A certain point of attention is that I changed
"program main" into
"subroutine f".
That really helped.

PS. Thanks to all who helped so quickly, especially Marty Shannon,
and also Dag Bruck.  Good work!

hugh@maths.tcd.ie (Hugh Grant) (11/17/88)

In article <1118@rivm05.UUCP> ccea3@rivm05.UUCP (Adri Verhoef) writes:
> [Describes problems using f77 and C++ together that causes a core
>	dump when using the streams routines]

As other people have pointed out, the problem arises from the fact that
the static constructors used in streams are not being initialised properly
inside the program resulting in a core dump. The suggestions put forward
do NOT work with any of the following:
	designer C++
	Glockenspiel C++
	domain C++
	Advantage C++

(which are all the same progam under different names). If you don't use
one of these, then refer to the previous postings.

There are two cases:

---------
CASE 1:	Calling C++ code from within a Fortran program


The C++ initialisation routine is called _entry() in these versions
and so the following (based on a previous posting) is required:

Declare the following function in your C++ code
	
	cxxinit()
	{
		_entry();
	}

and call CXXINIT from within your F77 code before you call any C++ routines.

--------
CASE 2:	Calling fortran libraries from within a C++ program

You should have no problems providing the "mxx" constructor linker is run
on the resulting executable, which should have happened if you used the "ccxx"
driver program to do the linking, e.g.

	f77 -c myfortran.f
	ccxx -o myprog myfortran.o f1.cxx f2.cxx

If you link the code by hand, just remember to run "mxx" afterwards.


Hope this helps,

	Hugh

--
Hugh Grant				hugh@maths.tcd.ie, hugh@puschi.uucp
Glockenspiel Ltd., Ireland		Phone: +353-1-364515
void Posting::Disclaimer() { Default(); }