El archivo programa.c es el mismo de la carpeta 2_ProgramaC-SubrutinaC. El archivo subrutina.f es el mismo de la carpeta 1_ProgramaFortran-SubrutinaFortran. El archivo enlace.c permite enlazar el programa C con la subrutina Fortran. Nótese que: - En Fortran la transferencia de argumentos se realiza por referencia (excepto en el caso de los argumentos de tipo character). - En C la transferencia de argumentos se realiza normalmente por valor salvo que se indique lo contrario (con el prefijo &), en cuyo caso se realiza por referencia. Se exceptúan los vectores, que se transfieren por referencia (ya que v, v[] y &v[0] son equivalentes). - Los compiladores Fortran no distinguen las mayúsculas de las minúsculas (salvo que contengan una opción de compilación que cambie esta forma de proceder). En particular, el compilador GFortran pasa a minúsculas los nombres de las subrutinas y les añade un guion bajo (carácter "_") al final. En otros compiladores el criterio puede ser diferente (puede que el nombre se pase a mayúsculas o que se añadan o no otros caracteres). - Los compiladores C distinguen las mayúsculas de las minúsculas. El compilador GCC conserva las mayúsculas y minúsculas en los nombres de las funciones. Por ello: - En el programa C la llamada ProductoEscalar(n, v, v, &w); se compila de forma equivalente a ProductoEscalar(n, &v[0], &v[0], &w); - La subrutina Fortran Subroutine ProductoEscalar(n,v1,v2,w) implicit real*8 (a-h,o-z) dimension v1(n), v2(n) ... end se compila de forma equivalente a la función C void productoescalar_(int *n , double *v1, double *v2, double *w) { ... } - Por ello, el programa C no se puede enlazar correctamente con la subrutina Fortran, ya que -- El nombre de la función a la que se llama no coincide con el de la función que recibe. -- El primer argumento se transfiere por valor y se recibe por referencia. Soluciones: 1) Modificar el programa C, de forma que la llamada se escriba como productoescalar_(&n, v1, v2, &w); Puede ser necesario reprogramar la subrutina Fortran si en su interior se modifica el valor de n, ya que de lo contrario se modificará el valor de n en el programa principal. 2) Añadir la función C auxiliar void ProductoEscalar(int n , double *v1, double *v2, double *w) { void productoescalar_(int *, double *, double *, double *); productoescalar_(&n, v1, v2, w); } que actuará como enlace entre el programa C y la subrutina Fortran. En esencia, esta función auxiliar recibe el primer argumento (n) por valor y el resto (v1, v2, w) por referencia y pasa los cuatro argumentos (n, v1, v2, w) por referencia a la subrutina Fortran. No será necesario reprogramar la subrutina Fortran aunque en su interior se modifique el valor de n, ya que el valor de n que se recibe será el de la función de enlace (que es una copia del valor de n en el programa principal).