Смешанное программирование на C-Fortran

Я работаю над проектом, в котором мне нужно использовать библиотеку Fortran на C. В библиотеке Fortran есть общий блок, содержащий сложный массив * 16, 4x4. Теперь в C сложная переменная представляет собой просто структуру, содержащую два элемента, и, поскольку она является комплексной * 16, элементы должны быть длинными двойными, что является соответствующим типом данных C в Фортране. Итак, у меня есть структура с двумя длинными двойниками.

Я должен получить доступ к элементам этого массива. Хорошо, что я уже могу сделать это вместе со всеми другими общими переменными библиотеки. Проблема в том, что элементы, которые я импортирую из массива,

1) Не в том порядке, в каком должен быть, "даже с учетом разницы в структуре массивов C и Fotran".

2) Хотя большинство элементов правильные, два из них сильно отличаются от того, чем они должны быть.

3) Я получаю правильные элементы (кроме двух), только если использую double вместо long double. Когда я использую long double (и правильное преобразование символов), я получаю совершенно другое, что явно указывает на проблему с преобразованиями.

Я исчерпал все объяснения, которые у меня были, но ничего не работает. Мой код для печати массивов в C выглядит следующим образом:

for (j=0;j<=3;j++){
    printf("%s", "\n");
    for(k=0;k<=3;k++){            
        printf("%s %d %s %d %s %s %LE %s %LE %s",
          "(", k+1, "," ,j+1, ")", "{",
          (long double)mssmmixing_.neunmx[k][j].dr,
          " ",
          (long double)mssmmixing_.neunmx[k][j].di,
          "}\n");           
    }
}

Дополнительная информация: поскольку мне приходится смешивать файлы объектов Fortran, я использую gfortran для компиляции файлов C. Если вместо этого я использую компилятор GNU C, он выдает ошибки о том, что не распознает подпрограммы gfortran. Это также может быть источником проблемы, может быть, gfortran не распознает длинные двойные числа в C.

Любая помощь будет полезна.


person Shaz    schedule 31.10.2011    source источник
comment
Я не уверен насчет long double. По моему (ограниченному) опыту C double соответствует Fortran real*8. А complex*16 по сути является парой real*8-ов. Вы пытались сделать игрушечный код на Фортране с общим блоком только из real*8?   -  person ev-br    schedule 01.11.2011
comment
Да, я сделал. Алгоритм, который я использую, работает для этого случая. Но не в моем случае.   -  person Shaz    schedule 01.11.2011
comment
хорошо, тогда станет ли лучше, если вы будете использовать только double, а не long double? А, э-э, случайно нет ошибок на единицу? --- Коды Fortran часто используют массивы с отсчетом от 1 вместо отсчета от 0.   -  person ev-br    schedule 01.11.2011


Ответы (1)


Для смешивания Fortran и C я рекомендую использовать ISO_C_Binding. У него даже есть тип Fortran C_LONG_DOUBLE_COMPLEX, который соответствует типу C long double _Complex -- см. http://gcc.gnu.org/onlinedocs/gfortran/ISO_005fC_005fBINDING.html. Как часть стандарта языка Fortran, эти типы гарантированно совпадают (при использовании совместимых компиляторов). Очень вероятно, что C_LONG_DOUBLE_COMPLEX на самом деле то же самое, что и complex*16, но вы можете попробовать в Фортране скопировать между двумя типами, если расположение памяти отличается. Вы должны скомпилировать исходные файлы Fortran с помощью gfortran и C с помощью gcc. Легче всего связать с gfortran. (Или используйте другие «фирменные» компиляторы.)

person M. S. B.    schedule 31.10.2011
comment
Спасибо. Я новичок в Фортране. Не могли бы вы немного подсказать, как использовать этот модуль. - person Shaz; 31.10.2011
comment
Поскольку мне приходится смешивать файлы объектов Fortran, я использую gfortran для компиляции файлов C. Я не очень понимаю, можно уточнить? - person Vladimir F; 01.11.2011
comment
Это означает, что когда я компилирую свой код C, он должен включать некоторые объектные файлы, скомпилированные в GFortran. Если я не использую компилятор GFortran, я получаю ошибки, потому что компилятор CC не распознает процедуры GFortran. - person Shaz; 01.11.2011