Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29285 Discussions

Calling Fortran Module variables and pocedures form C++

MWind2
New Contributor III
3,436 Views
I had some old code for gfortran that I cannot seem to get right on Windows using 10.0.025 and VS05:
[fortran]MODULE FMATRIX
      TYPE :: ptrd
        REAL(8),POINTER :: PD
      END TYPE
      TYPE (ptrd),DIMENSION(4,4) :: AXP
      PUBLIC AXP
      REAL(8), DIMENSION(4,4), TARGET :: AX
      PUBLIC AX
      REAL (8), TARGET :: MX(4,3,2)
      PUBLIC MX
      TYPE (ptrd) :: MXP(4,3,2)
      PUBLIC MXP
      CONTAINS
      SUBROUTINE FINIT
      DO I=1,4,1
        DO J=1,4,1
           AX(I,J)=I*4.0+J-5.0
           AXP(I,J)%PD=>AX(I,J)
        END DO 
      END DO 
      END SUBROUTINE FINIT 
            SUBROUTINE MINIT
      DO I=1,4,1
        DO J=1,3,1
          DO K=1,2,1
            MX(I,J,K)=I*6.0+J*2 + K -9.0
            MXP(I,J,K)%PD=>MX(I,J,K)
          END DO 
        END DO 
      END DO  
      END SUBROUTINE MINIT
             
      END MODULE FMATRIX[/fortran]

[bash]#include 
#include 
typedef struct {double * pd;} PTRD;
#define X0MAX 4
#define X1MAX 3
#define X2MAX 2
// extern "C" PTRD AXP[X0MAX][X0MAX];
extern "C" double AX[X0MAX][X0MAX];
extern "C" void FINIT(void);

// extern "C" void MINIT(void);
int main(int argc, char* argv[])
{   int ndx0,ndx1,ndx2;
	FINIT();
	for (ndx0=0;ndx0<4;ndx0++)
		for (ndx1=0;ndx1<4;ndx1++) // display with c indexing of fortran array
	{    printf("AX[%d,%d]=%f\n",ndx0,ndx1,AX[ndx0][ndx1]);
         //    printf("AX[%d,%d]=%f; AXP[%d,%d]=%08p\n",ndx0,ndx1, \
	     // AX[ndx0][ndx1],ndx0,ndx1,AXP[ndx0][ndx1].pd);
	}
	// MINIT(); */
	return 0;
}
What do I need to do to access AX and FINIT?[/bash]
0 Kudos
1 Solution
mecej4
Honored Contributor III
3,436 Views
Running Dumpbin on the object file from the Fortran part will show you what the C names for the module procedures are. With ICL 12.1 and IFort 12.1, I get the names as

FMATRIX_mp_FINIT
FMATRIX_mp_AX

View solution in original post

0 Kudos
12 Replies
mecej4
Honored Contributor III
3,437 Views
Running Dumpbin on the object file from the Fortran part will show you what the C names for the module procedures are. With ICL 12.1 and IFort 12.1, I get the names as

FMATRIX_mp_FINIT
FMATRIX_mp_AX

0 Kudos
MWind2
New Contributor III
3,436 Views
I'm a silly wabbit. I was using lowercase fmatrix.
0 Kudos
TimP
Honored Contributor III
3,436 Views
Among the uses of iso_c_binding is to fix the link symbols so they don't vary with Fortran implementations.
0 Kudos
MWind2
New Contributor III
3,436 Views

Where are constants defined like 0_C_INTPTR_T as in

[fortran] pINT =  transfer(c_loc(AXP(I,J)), 0_C_INTPTR_T)
          write( *, 100 ) pINT
100       format( Z8 ) [/fortran]

Though I'm using 10.0.025, my helpfile does not seem to list such.
0 Kudos
Steven_L_Intel1
Employee
3,436 Views
You need to have:

USE, INTRINSIC :: ISO_C_BINDING

in the program unit where you use that constant. C_INTPTR_T is a parameter constant defined in that module. 10.0 was the first release to support this. The usage here means an integer 0 of kind C_INTPTR_T, which is the kind that is the size of a C pointer (or address).
0 Kudos
MWind2
New Contributor III
3,436 Views
Thanks. I guess I forgot to say I had an
[fortran]use iso_c_binding[/fortran]

in there; my second question was where I might find definitions of such constants? Web search and directory contents search does not seem to turn up anything for 0_C_INTPTR_T. Are there more or is this special? Or is it enumerated by some type values as in "result = transfer(source, mold) where mold is

(Input) Must be a scalar or array (of any data type). It provides the type characteristics (not a value) for the result.
0 Kudos
anthonyrichards
New Contributor III
3,436 Views
0 Kudos
IanH
Honored Contributor III
3,436 Views
What do you mean by "definitions"?

If you look in the useful links section at the top of the forum you'll see links to the F2008 (and F2003) standard. Have a look a chapter 15 in the F2008 document (interoperability with C), there's similar content in the F2003 document.

I don't have access to 10.x, but ifort 12.1 has similar content in its help in topics under the ISO_C_BINDING intrisic module.
0 Kudos
Steven_L_Intel1
Employee
3,436 Views
10.x didn't have Intel documentation of these features. As noted, they are described in the Fortran 2003 and 2008 standards, and in current Intel documentation.
0 Kudos
MWind2
New Contributor III
3,436 Views
I've found C_INTPTR_T in even the 10.0.25 docs as well as the F2008 standard, but not 0_C_INTPTR_T. What other prepending '0_' are known constants?
0 Kudos
IanH
Honored Contributor III
3,436 Views
All this just elaborates on post #5. The 0 part just means a value of zero. 1_C_INTPTR_T means a constant of value 1, 2_C_INTPTR_T means a constant of value 2, etc. The set of integer values is ... quite large!

The first _ is a Fortran 90 language syntax aspect that separates the value of the constant from its "kind". The kind tells the compiler that a particular representation (number of bytes in memory, etc) should be used to store the constant. In the case of 0_C_INTPTR_T the kind is C_INTPTR_T.

Kinds can either be numbers themselves (0_4 is a constant with value zero represented with kind 4) or symbolic constants (which will be ultimately be defined to be some sort of number - for example C_INTPTR_T happens to be 8 with 64 bit ifort, on that specific compiler 0_C_INTPTR_T is equivalent to 0_8). What's valid as a kind and what a particular kind number means is compiler dependent (on ifort it is the number of bytes used in the representation). A compiler specific default kind is used for constants and variables that don't otherwise have a kind specified.

As the standard and docs will say, C_INTPTR_T tells the compiler that the zero needs to be represented in the same way that the C language represents an object of type intptr_t.

The transfer intrinsic that you had in your example in post #4 doesn't actually care about the value of the second argument (the MOLD argument) - it just uses that argument as a template for the characteristics of the result of the transfer - "transfer the result of the expression c_loc(AXP(I,J)) so that it looks like an integer of kind C_INTPTR_T".

I'm not sure how this relates to your original query though... you should be able to get access to the module variables easily enough with the BIND attribute. How did we get onto C_LOC, C_INTPTR_T, etc?
0 Kudos
MWind2
New Contributor III
3,436 Views
Post #4. Thanks for the explanation. I am mostly from c++ world and had never seen the _ use.
0 Kudos
Reply