LINUX.ORG.RU

Проблема вызова подпрограмм на fortran из cpp

 , ,


0

3

Используются g++ и gfortran (Debian 4.7.2-5)
Программа содержится в main.cpp. В ней создается двухмерный массив типа double:

   double A[10][10] = {
        {1.0, -6.0, 3.0},
        {-7.0, 9.0, -4.0},
        {0.0, 4.0, 2.0},
    };


Размер 10x10 обусловлен подпрограммой на фортране.

Для вызова подпрограммы из файла foo.f90 используется следующая запись:

extern "C" {
    void foo_(..., double(*)[10]);
}
Далее матрица передается foo:
foo_(..., &A);
Программа компилируется следующей командой:
g++ main.cpp foo.f90 -o test -lgfortran

Надо сказать, что результаты вычислений правильные(их можно перепроверить) и эта конструкция, в целом, работает.

Однако, подобный трюк не проходит с подпрограммами на фортран 77, которые содержатся в файлах *.f. Это подрограммы тоже проверены, и точно правильные. Работа с двумерным массивом не происходит.

Я нашел хороший мануал на эту тему:
http://arnholm.org/software/cppf77/cppf77.htm#Section3.5.2 Здесь есть примеры и для одномерных и для двумерных массивов.

Например:

      SUBROUTINE F77SUB(LARR,ARRAY)
      INTEGER           LARR
      REAL              ARRAY(LARR)
      INTEGER I
C
C     Assign values to the array passed from C++
C     Note: indices run from 1 to LARR inclusive !
C
      DO 1000 I=1,LARR
         ARRAY(I) = REAL(I*I)
1000  CONTINUE
      RETURN
      END

#include <fortran.h>
SUBROUTINE F77SUB(INTEGER& LARR, // integer passed by reference
                  REAL* ARRAY);  // real array pointer passed
void cppfunc()
{
   const INTEGER size=10;
   REAL    ARRAY[size];
   INTEGER LARR=size;
   .
   F77SUB(LARR,ARRAY);             // ARRAY == &ARRAY[0]
   .
   .
// here you can use the assigned contents of ARRAY,
// Note: indices run from 0 to LARR-1 inclusive !
   .
   .
   return;
}

Но совершенно непонятно как компилировать такой код? При попытке сделать

g++ main.cpp f77sub.o  -o test
возникает ошибка:
main.cpp:1:21: fatal error: fortran.h: No such file or directory
compilation terminated.
Если установить cfortran и поставить #include <cfortran.h> то ошибок еще больше.

Вопросы:
1. Как откомпилировать программу из примера?
2. Использовать ли cfortran?
3. Использовать ли конструкцию extern"C" в файле main.cpp?
4. Какие еще есть идеи?

Deleted

Последнее исправление: Deleted (всего исправлений: 2)

Телепатия mode, не читая тред

А ты учитываешь, что все эти real и integer в фортране на самом деле указатели?

Или ты только массивы передаешь?

stopitplease
()

Зачем тебе фортран? :-) ну есть же V8 и православный Lua JIT. Если ты для науки стараешься - то смотри в сторону внедрения python интерпретатора в C++.

menangen ★★★★★
()

В фортране НЕТ двумерных массивов. «Многомерные массивы в фортране» — это одномерные развернутые по столбцам. Например, матрица

a₁₁ a₁₂
a₂₁ a₂₂ 
представляется в фортране как
a₁₁ a₂₁ a₁₂ a₂₂
Соответственно, не надо городить огород и всегда передавать массивы в фортран как double*.

unanimous ★★★★★
()

g++ main.cpp foo.f90 -o test -lgfortran

У тебя какая-то магия на макросах, которая генерирует из исходников на фортране код на C++. И с фиксированным форматом fortran77 эти макросы не справляются. Наверное, стоит посмотреть в сторону компиляции gfortran'ом в объектные файлы.

i-rinat ★★★★★
()

2. Использовать ли cfortran?

По остальным пунктам не скажу, но сам сейчас по диплому ковыряю огромный код на фортране. Руководитель советовал использовать ifort. Для некоммерческого использования он бесплатен.

solovey ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.