Как перепроектировать библиотеку смешанных языков Fortran и C++ из общих блоков — глобальные псевдонимы структур?

У меня есть программа, состоящая в основном из Fortran 77 с оболочкой C++, которая читает и записывает в базу данных. Две части приложения совместно используют данные, используя функцию, которая, если вы используете глобальную структуру C/C++, названную как общий блок Fortran. Я почти уверен, что этот подход к интеграции C++/Fortran с псевдонимами 1) работает для многих наборов компиляторов, 2) не является стандартным. Я стараюсь поддерживать свой код так, чтобы он максимально использовал стандартные компоненты. Кроме того, эта интеграция оказалась хрупкой.

В утд.ч:

/*************************************************************
 *  This struct must follow the common block points.
 *  See the Fortran include file points.i
 *************************************************************/
typedef struct ALIGN points
{
    double  point[3][MAX_PTS];
    double  edge[3][MAX_PTS];
    double  edgenorm[3][MAX_PTS];
    double  edgerho[MAX_PTS];
    int     nfacets[MAX_PTS];
    double  facet1[3][MAX_PTS];
    double  facet2[3][MAX_PTS];
    double  gaussk[MAX_PTS];
    int     sbstin[MAX_PTS];
    int     coatin[MAX_PTS];
    int     sbstout[MAX_PTS];
    int     coatout[MAX_PTS];
    int     ncorners[MAX_PTS];
    double  cnrpoint[3][MAX_CNRS][MAX_PTS];
    int     ncnredgs[MAX_CNRS][MAX_PTS];
    double  cnredge[3][MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     cnrsbst[MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     cnrcoat[MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     npoints;
} POINTS;

extern POINTS  points_;

В утд.cpp:

POINTS  points_;

В пунктах.i:

  !  maxpnt  -  maximum number of points in a path.
  integer  maxpnt
  parameter ( maxpnt = 1000 )

  integer npoints, nfacets(maxpnt)
  integer ncorners(maxpnt), ncnredgs(maxpnt,maxcorners)
  integer sbstin(maxpnt), coatin(maxpnt)
  integer sbstout(maxpnt), coatout(maxpnt)
  double precision point(maxpnt,3)
  double precision edge(maxpnt,3), edgenorm(maxpnt,3)
  double precision edgerho(maxpnt)
  double precision facet1(maxpnt,3), facet2(maxpnt,3)
  double precision gaussk(maxpnt), cnrpoint(maxpnt,maxcorners,3)
  double precision cnredge(maxpnt,maxcorners,maxcnredges,3)
  integer cnrsbst(maxpnt,maxcorners,maxcnredges)
  integer cnrcoat(maxpnt,maxcorners,maxcnredges)

  common /points/ point, edge, edgenorm, edgerho,
 *                nfacets, facet1, facet2, gaussk,
 *                sbstin, coatin, sbstout, coatout,
 *                ncorners, cnrpoint, ncnredgs,
 *                cnredge, cnrsbst, cnrcoat,
 *                npoints

Есть ли способ лучше? Я мог бы преобразовать общие блоки в модули. Тогда я уверен, что этот бизнес с псевдонимом общего блока с глобальной структурой невозможен. Как вы создаете модуль Fortran из C++? Как вы читаете данные из такого модуля?

Что вы посоветуете по поводу интеграции C++/Fortran?


person emsr    schedule 04.08.2012    source источник
comment
Не знаю, подойдет ли это для вашей цели, но мне на ум приходит этап препроцессора, который читает спецификационный файл и автоматически генерирует из него код C++ и Fortran. Сделайте это частью процесса сборки, и ваши файлы C++ и Fortran больше не будут рассинхронизированы.   -  person Jeremy Friesner    schedule 04.08.2012


Ответы (1)


Привязка ISO C к Fortran 2003 делает совместимость C и Fortran частью стандарта языка Fortran и, следовательно, компилятор и переносимую платформу. Если вы используете только функции C, скорее всего, это будет работать и на C++, хотя, возможно, это не гарантируется абсолютно. Вы можете смешивать Fortran 2003 и FORTRAN 77 либо в исходном файле, либо путем смешивания подпрограмм, написанных на двух версиях этих языков. Привязка ISO C поддерживает структуры и переменные модулей в качестве глобальных переменных, поэтому она может достигать ваших целей. Оба они показаны в главе «Программирование на смешанных языках» руководства gfortran. (Привязка ISO C не относится к gfortran, я цитирую это как хороший документ.)

Общие блоки также поддерживаются, но я согласен с вами, лучше избегать ... общие блоки добавляют последовательность хранения FORTRAN и макет, что не нужно. Я не вижу никакого способа вручную поддерживать «структуры» C и Fortran, чтобы иметь эквивалентные объявления. Если это причина хрупкости, вам просто нужно быть осторожным (запретить написание программы для написания обоих из общих инструкций). Один из подходов, который сделал бы это немного проще, заключался бы в том, чтобы не помещать переменные в структуру... тогда неправильная установка новой переменной с меньшей вероятностью повлияет на старые переменные, и это может облегчить обнаружение или отладку ошибки.

person M. S. B.    schedule 04.08.2012
comment
Если я использую ISO_C_BINDING, нужен ли мне extern "C" в функциях C++? Я проверю документы по смешанным языкам gfortran. Я думаю, что смотрел на старую версию Fortran77ish, когда начинал этот проект 10 лет назад. - person emsr; 06.08.2012