Lo escribo como respuesta porque los comentarios están demasiado restringidos para pronunciar esto.
esta pregunta trata de explicar las diferencias en la distribución de la memoria de matrices y registros en FORTRAN y Delphi y modifica el answer por Todd Grigsby y la answer por Remy Lebeau (I upvoted ambos).
FORTRAN y algunos otros idiomas céntricos de cálculo almacenan matrices anidadas en column major order. Delphi y muchos otros idiomas usan un row major order.
Desde una perspectiva de memoria, un disco no es más que una serie de campos que:
- tener un nombre y no un índice
- puede tener diferentes tipos
Para el cálculo intensivo operaciones, puede tener sentido almacenar orden jerarquizada de columnas anidadas cuando sus algoritmos favorecen las columnas. Lo mismo para la orden principal de la fila. Entonces en loops, necesitas match the order of your indexes with the order of your storage.
Dada esta definición de registro y la matriz en FORTRAN:
TYPE WallInfo
CHARACTER(len=40) :: Name
REAL :: Azimuth
REAL :: Tilt
REAL :: Area
REAL :: Height
END TYPE WallInfo
TYPE(WallInfo), ALLOCATABLE, DIMENSION(:) :: Wall
y la definición equivalente funcional en Delphi:
type
WallInfo = record
Name: array[0..39] of Char;
Azimuth: Real;
Tilt: Real;
Area: Real;
Height: Real;
end;
var
Wall: array of WallInfo;
y un conjunto de 3 elementos WallInfo, así es como el diseño de memoria se vería (todas serían áreas de memoria continuas, las dividí en líneas para mantenerlas legibles):
en 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],
en 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],
Así que esta llamada FORTRAN:
LLAMADA flujo de calor (Wall% Área, Wall% acimut)
habría sólo tiene que pasar los punteros de la zona [ 0] y Azimuth [0] ubicaciones de memoria y longitud de esas áreas de memoria para la función.
En Delphi, eso no es posible, así que hay que
- construir nuevo Espacio y Azimut Arays
- copiarlos de la información en la matriz de la instancia de registro WallInfo llama Wall
- enviarlos a la función
- si estos son parámetros var: copiar los cambios de las dos matrices de nuevo a la pared
Todd Grigsby y Remy Lebeau mostraron los primeros tres pasos en su respuesta usando código Delphi directo, o registro RTF de Delphi.
El paso 4 funciona de manera similar.
Ambas soluciones usan genéricos que se introdujeron en Delphi 2009.
Until Delphi 2010, RTTI on records was very minimal), por lo que obtuvo la versión correcta de Delphi para ambas respuestas.
Nota (otra vez): al traducir los algoritmos de FORTRAN a Delphi, asegúrese de mirar los bucles y otras indexaciones en las matrices debido al cambio importante de columna/fila.
¿Intentó con una matriz o grabó en su matriz de caso de WallInfo? Delphi admite matrices dinámicas. Antes de ingresar un nuevo valor, primero configure el tamaño de la matriz con SetLength. –
Por muy buena que sea la respuesta RTTI de Remy, me sentiría tentado a traducir el tipo de registro anterior en matrices lineales separadas: 'Nombre: matriz de cadena; Azimuth: matriz de doble; ... 'y luego no tendría que recopilar los datos usando este encantador truco RTTI porque ya estaría reunido. –