Cross-Language Communication problem between FORTRAN & C.

Calvin H. Vu calvin at dinkum.wpd.sgi.com
Tue Nov 13 06:18:43 AEST 1990


In <1990Nov9.212649.27564 at athena.mit.edu> mlzerkle at athena.mit.edu (Michael L Zerkle) writes:

| I am trying to develop C functions to allocate and deallocate arrays
| for use in a FORTRAN progam that would run on a number of different
| UNIX boxes (DEC VS3100, Apollo, SGI 4D/210, etc.).  The C functions
| I have written appear to allocate the double array correctly, but
| either it does not pass it back the the FORTRAN program correctly, or
| the FORTRAN program is not accepting the pointer/array it is returning.
| 
| Does anyone out there have any experience with problems of this sort,
| or know what I am doing wrong?  Any suggestions?

You cannot assign an address to an array at runtime to turn the array into a 
relocatable array.  On SGI systems,  the type POINTER is supported to allow
you to do this (see the latest F77 Reference Manual on POINTER specification
if you have one).  For example:
	real*8 a(1)
	pointer (ptr, a)
	maxa = 5
C   You have to use an assignment (or DATA statement) to give 'ptr' a value
C   since it doesn't have a storage allocated for it i.e. you cannot
C   use it as an actual argument and assign a value to it in the called
C   subroutine
	ptr = malloc(maxa*8)
	do i=1,maxa
	  a(i) = i
	enddo
	end
For systems which do not support POINTER type you can do the following
trick:
	integer ptr, maxa
	maxa = 5
	ptr = malloc(maxa*8)
	call malloc_array(%val(ptr)) !pass value of ptr to be used as address
	end
	subroutine malloc_array(a)
	dimension a(1)
	do i=1,maxa
	  a(i) = i
	enddo
	return
	end

The following is a modified version of your program which works on SGI
systems (and DEC).  

      program testgetm
      real*8 a(1)
      pointer (ptr, a)
      integer*4 maxa,bytesa,i
c      external getmd,freemd
c
      maxa=5
      bytesa=8
c
c Write Initial location.
c
      write(6,'(a)') 'Initial address'
c      write(6,*) ptr,maxa,bytesa
c
c Allocate real*8 array.
c
c       call getmd(ptr,maxa)
	ptr = malloc(maxa*8)
c
c Write addresses
c
      write(6,'(a)') 'Final address'
c      write(6,*) ptr,maxa,bytesa
c
c Work on array
c
      write(6,'(a)') 'REAL*8 array '
      if (ptr.ne.0) then
       	 do 10 i=1,maxa
           a(i)= 1.0d+0*i
	    write(6,*) i, a(i)
 10      continue
      else
	 write(6,'(a)') ' Unable to allocate r*8 array a'
      endif
c
c Free arrays.
c
c      if (loc(a).ne.0) call freemd(a)
       if (ptr.ne.0) call free(ptr)
c
      stop
      end

Hope it helps,

- calvin
--
-----------------------------------------------------------------------------
Calvin H. Vu			   | "We are each of us angels with only one
Silicon Graphics Computer Systems  | wing.  And we can only fly embracing
calvin at sgi.com   (415) 962-3679	   | each other."



More information about the Comp.sys.sgi mailing list