[net.lang.f77] Query: Sharing f77 COMMONs with C Externals

peters@cubsvax.UUCP (Peter S. Shenkin) (05/03/86)

Is there an easy way to do this without duplicating storage?
For the moment I'd like to do input into COMMONs using existing f77 routines
and have the data magically appear in C externals, although I can imagine
wanting to do the reverse sometime....

I suppose I could do this simply by calling an f77 routine from C and returning
the COMMON data into C externals, but this would involve a duplication of 
storage....

Peter S. Shenkin	 Columbia Univ. Biology Dept., NY, NY  10027
{philabs,rna}!cubsvax!peters		cubsvax!peters@columbia.ARPA

kenward@mdivax1.UUCP (kenward) (05/06/86)

I have a fortran graphics program that passes a single value through named 
common to a C routine.

    FORTRAN:

      COMMON /FOO/ BAR


    C:

      import struct { int bar; } foo_;

I am not conversant in C, but this looks like it would work in general -- that 
is, with longer commons.

Hope this helps,

Gary W. Kenward
Mobile Data International Inc.
Riverside Industrial Park
Richmond, B.C.
Canada  V7A 4Z3

Plus ca change, plus c'est la meme chose!

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SNAP! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-- 

Gary W. Kenward
Mobile Data International Inc.
Riverside Industrial Park
Richmond, B.C.
Canada  V7A 4Z3

Plus ca change, plus c'est la meme chose!

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SNAP! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

donn@utah-cs.UUCP (Donn Seeley) (05/07/86)

At least on the VAX under 4.3 BSD, f77 COMMON blocks are represented in
exactly the same way as C externals.  The following two files, one
Fortran and one C, demonstrate the correspondence:

------------------------------------------------------------------------
	integer a
	real b(4)
	double complex c
	character*4 d
	integer*2 e(2)
	complex f
	common /z/ a, b, c, d, e, f

	a = 1
	b(1) = 2.
	c = (3., 4.)
	d = 'a'
	e(2) = 5
	f = (6., 7.)

	call croutine
	stop
	end
------------------------------------------------------------------------
struct complex { float r, i; };
struct double_complex { double dr, di; };
struct z {
	int a;
	float b[4];
	struct double_complex c;
	char d[4];
	short e[2];
	struct complex f;
} z_;

void
croutine_()
{
	printf("%d %f %f %.4s %hd %f\n",
		z_.a,
		z_.b[0],
		z_.c.di,
		z_.d,
		z_.e[1],
		z_.f.r);
}
------------------------------------------------------------------------

Notice the difference in the origin for arrays...  A properly aligned
f77 COMMON block should produce a properly aligned C structure.

Donn Seeley    University of Utah CS Dept    donn@utah-cs.arpa
40 46' 6"N 111 50' 34"W    (801) 581-5668    decvax!utah-cs!donn

kenward@mdivax1.UUCP (kenward) (05/07/86)

<>
Organization: Mobile Data International Inc., Rich., B.C., Canada
Lines: 22

My apologies to the net for the previous two muck ups.  Can't explain it, but
hopefully it won't happen again.  (If two copies of this message are posted, 
then I'll know that there is something wrong system wise)

By the way, the 4.2bsd convention appears to be that named commons have an 
underscore appended to them, and may be so referenced from C.  This from the 
"A Portable Fortran 77 Compiler", Feldman and Weinberger, Bell Labs.  

There is no mention that I can find on how to reference the fields of the 
common block, that I can find.

-- 

Gary W. Kenward
Mobile Data International Inc.
Riverside Industrial Park
Richmond, B.C.
Canada  V7A 4Z3

Those who can do, those who cannot simulate.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SNAP! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

sgcpal@watdcsu.UUCP (P.A.ul Layman [EE-Device Physics]) (05/10/86)

In article <204@mdivax1.UUCP> kenward@mdivax1.UUCP (kenward) writes:
>By the way, the 4.2bsd convention appears to be that named commons have an 
>underscore appended to them, and may be so referenced from C.
>
>There is no mention that I can find on how to reference the fields of the 
>common block, that I can find.
>
Provided the common block is not blank common.  This refering to the
single common block available in f77 which does not have a name such as

	common //a,b,c,...

It is not a great problem. Merely extern the name of the common block
in your c program.  Just make sure you define it to be the same data type.
The following is a simple example which defines the elements of a real*4
common block in a fortran program then makes use of it in a c subroutine.

main program test.f
_____________________________________
	common /x/y
	real y(10)
	do 100 i=1,10
100	y(i)=i
	call comtst
	stop
	end
_____________________________________
subroutine comtst.c
_____________________________________
#include <stdio.h>
comtst_()
{
	extern float x_[];
	int i;
	for ( i=0 ; i<=9 ; i++ )
	    {
	    printf("x(%d) = %f\n",i,x_[i]);
	    }
	return(0);
}
_____________________________________
Note that the name used in the c routine is that of the "common block", x,
not that of the array used in the mainline, y, which is mapped into the
common block.  This name was only local to the mainline.  If you want
to use the same name in the c routine, you'll have to use pointers to elements
of the x_ array, but they won't have to have the "_" appended, because
they will again only be local.

I hope this helps.

PAul

P.S. it is sometime useful to use the -S option of f77 to look at
the assembler code of both the c program and the f77 program if you want
to see how they interact.

sgcpal@watdcsu.UUCP (P.A.ul Layman [EE-Device Physics]) (05/10/86)

In article <2278@watdcsu.UUCP> I (P.A.ul Layman [EE-Device Physics]) write:
>Provided the common block is not blank common.  This refering to the
>single common block available in f77 which does not have a name such as
>
>	common //a,b,c,...
>
>It is not a great problem. Merely extern the name of the common block
>in your c program.  Just make sure you define it to be the same data type.
>
I just heeded my own advice and looked at the assembler for a f77 program with
a blank common block.  This too can be accessed from c using the name _BLNK__
as in the following example:
main program test.f
_____________________________________
	common //y
	real y(10)
	do 100 i=1,10
100	y(i)=i
	call comtst
	stop
	end
_____________________________________
note that the common statement could also be common y, it makes no differenece.
subroutine comtst.c
_____________________________________
#include <stdio.h>
comtst_()
{
	extern float _BLNK__[];
	int i;
	for ( i=0 ; i<=9 ; i++ )
	    {
	    printf("_BLNK_(%d) = %f\n",i,_BLNK__[i]);
	    }
	return(0);
}
_____________________________________

PAul