Fortran common blocks and C/C++ structures

When you want to access variables in Fortran common blocks from C/C++ you need to define structs in C/C++ that matches the common blocks. This, of course, also provides means to manipulate the common blocks in Fortran in order to transfer information to your C/C++ code.

Important. Read this carefully, it can save you a lot of time.
Note that the order of the variables, and array sizes, within the common block and structure is very important. When the linker reaches a common block or structure definition it assigns a memory area for the whole block of variables. The variables are referenced consecutively within this memory area. A mismatch in the common block and the structure definitions will naturally lead to conflicting variable references.



Example

Fortran definition of a common block:

      COMMON /LUJETS/ N,K(4000,5),P(4000,5),V(4000,5)
      SAVE /LUJETS/



Corresponding straightforward C/C++ struct definition. (Note the reversion of array indices.)

extern "C" /* this line should be omitted in C */
{
extern struct {
  int   n;		/* nof lines occupied in matrices below	*/
  int   k[5][4000];	/* k[0][i] status code KS 		*/
			/* k[1][i] particle code KF		*/
			/* k[2][i] line nof parent particle/jet	*/
			/* k[3][i] normally line nof 1st daugther */
			/* k[4][i] normally line nof last daught. */ 
  float p[5][4000];	/* p[0][i] p_x, momentum in Gev/c	*/
			/* p[1][i] p_y, momentum in Gev/c	*/
			/* p[2][i] p_z, momentum in Gev/c	*/
			/* p[3][i] E, energy in Gev		*/
			/* p[4][i] m, mass in Gev/c^2		*/
			/*         when Q^2=-m^2 >0, p[4][i]=-Q	*/
  float v[5][4000];	/* v[0][i] x position of vertex, in mm	*/
			/* v[1][i] y position of vertex, in mm	*/
			/* v[2][i] z position of vertex, in mm	*/
			/* v[3][i] time of production, in mm/c	*/
			/* v[4][i] proper lifetime, in mm/c	*/
} lujets_;
}



Variant C/C++ struct definition. Here a struct eventrecord is defined, and then used to declare the variables lujets_ and another_eventrecord. Later a statement like another_eventrecord=lujets_; can be issued. (Note the reversion of array indices.)

struct eventrecord {
  int   n;		/* nof lines occupied in matrices below	*/
  int   k[5][4000];	/* k[0][i] status code KS 		*/
			/* k[1][i] particle code KF		*/
			/* k[2][i] line nof parent particle/jet	*/
			/* k[3][i] normally line nof 1st daugther */
			/* k[4][i] normally line nof last daught. */ 
  float p[5][4000];	/* p[0][i] p_x, momentum in Gev/c	*/
			/* p[1][i] p_y, momentum in Gev/c	*/
			/* p[2][i] p_z, momentum in Gev/c	*/
			/* p[3][i] E, energy in Gev		*/
			/* p[4][i] m, mass in Gev/c^2		*/
			/*         when Q^2=-m^2 >0, p[4][i]=-Q	*/
  float v[5][4000];	/* v[0][i] x position of vertex, in mm	*/
			/* v[1][i] y position of vertex, in mm	*/
			/* v[2][i] z position of vertex, in mm	*/
			/* v[3][i] time of production, in mm/c	*/
			/* v[4][i] proper lifetime, in mm/c	*/
};

extern "C" /* this line should be omitted in C */
{
extern struct eventrecord	lujets_;
}
struct eventrecord		another_eventrecord;
       /* another_eventrecord could (should?) be a local variable
          within the C/C++ code */




This page was created April 7, 1999
Latest change was made on June 20, 2007.
mail to: webmaster@chiralcomp.com

©1999-2007 Chiral Data HB All Rights Reserved