I am posting this as an answer because the comments are too limited to express it.
This answer attempts to explain the differences in layout layouts of arrays and records in FORTRAN and Delphi and modifies Todd Grigsby 's answer and Remy Lebo's answer (I saved both).
FORTRAN and several other oriented oriented languages ββstore nested arrays in the column ordinal . Delphi and many other languages ββuse the basic string order .
From the point of view of memory, a record is nothing more than an array of fields, which:
- have a name, not an index
- can have different types
For intensive computing operations, it might make sense to store the basic column order of nested arrays when your algorithms favor the columns. The same goes for a large row order. Therefore, in loops, you need to match the order of your indexes with the storage order .
Given this entry and array definition in FORTRAN:
TYPE WallInfo CHARACTER(len=40) :: Name REAL :: Azimuth REAL :: Tilt REAL :: Area REAL :: Height END TYPE WallInfo TYPE(WallInfo), ALLOCATABLE, DIMENSION(:) :: Wall
and a functionally equivalent definition in Delphi:
type WallInfo = record Name: array[0..39] of Char; Azimuth: Real; Tilt: Real; Area: Real; Height: Real; end; var Wall: array of WallInfo;
and an array of 3 WallInfo elements, the memory layout will look like this (they will all be solid memory areas, I divide them into lines so that they can be read):
in FORTRAN:
Name[0,0]...Name[0,39], Name[1,0]...Name[1,39], Name[2,0]...Name[2,39], Azimuth[0], Azimuth[1], Azimuth[2], Tilt[0], Tilt[1], Tilt[2], Area[0], Area[1], Area[2], Height[0], Height[1], Height[2],
in Delphi:
Name[0,0]...Name[0,39], Azimuth[0], Tilt[0], Area[0], Height[0], Name[1,0]...Name[1,39], Azimuth[1], Tilt[1], Area[1], Height[1], Name[2,0]...Name[2,39], Azimuth[2], Tilt[2], Area[2], Height[2],
So this FORTRAN call:
CALL HeatFlow (Wall area%, wall% azimuth)
just pass pointers to memory areas [0] and Azimuth [0] and the length of these memory areas.
In Delphi this is not possible, so you need to
- build a new Area and Azimuth arays
- copy them from the information in the array of the WallInfo record instance called Wall
- send them functions
- If these are var parameters: copy the changes from the two arrays back to Wall
Todd Grigsby and Remy Lebo demonstrated the first three steps in their answer using the direct Delphi code, or Delphi RTTI record.
Stage 4 works in a similar way.
Both solutions use the generics that were introduced in Delphi 2009.
Prior to Delphi 2010, RTTI on the record was very minimal ), so you got the correct version of Delphi for both answers.
Note (again): when translating your algorithms from FORTRAN to Delphi, make sure that you are observing loops and other indexing in arrays due to a large column / row change.