У меня есть большая, смешанная база кода C / Fortran, в настоящее время скомпилированная с использованием инструментов Intel в Windows. Меня попросили перенести его на инструменты GNU в Linux. Более-менее случайно я выбрал версию 4.8.
Когда функция C вызывается из Фортрана, взаимодействие часто выглядит следующим образом:
// C code:
void PRINTSTR(char *str, size_t len) {
for(int ii = 0; ii < len; ii++) {
putchar(str[ii]);
}
putchar('\n');
}
!Fortran code:
program test
implicit none
call printstr("Hello, world.")
end
Компилятор Intel Fortran всегда генерирует символы в верхнем регистре, так что это прекрасно работает. Но компилятор GNU Fortran всегда генерирует символы нижнего регистра, поэтому возникает ошибка компоновщика.
В компиляторе GNU Fortran раньше была опция -fcase-upper
, которая заставляла его генерировать символы верхнего регистра, но похоже, что это было слишком настраиваемым для всеобщего блага, и он был удален (я не совсем уверен, когда).
Можно использовать функцию ISO_C_BINDING
, чтобы заставить компилятор генерировать имя с учетом регистра:
program test
interface
subroutine printstr(str) bind(C, name='PRINTSTR')
character :: str(*)
end subroutine
end interface
call printstr("Hello, world.")
end
Это устраняет ошибку компоновщика, но меняет способ обработки строковых параметров; параметр длины больше не предоставляется. Поэтому, чтобы использовать этот метод, мне пришлось бы не только добавить определения интерфейса для каждой функции, которая в настоящее время работает таким образом, но мне также пришлось бы изменить способ обработки строк при каждом вызове такой функции, убедившись, что все строки заканчиваются нулем.
Я мог бы пройти и сделать все такие функции в нижнем регистре, но, конечно, компилятор Intel по-прежнему генерирует символы в верхнем регистре, так что это нарушит существующую сборку.
Поскольку существует ~ 2000 таких функций, это кажется невыполнимым объемом работы. Итак, мой вопрос таков: как я могу устранить ошибки связи, не меняя семантику вызова функций и не нарушая существующую сборку с помощью компиляторов Intel?
size_t
, тогда как GFortran используетint
. Это нормально для 32-битных систем, но ужасно ломается в 64-битных системах, передавая более одной строки за раз, и компоновщик даже не улавливает их. - person Tristan Brindle   schedule 15.10.2014-fcase-upper
, был g95, а не GFortran (который теперь является официальным компилятором GNU Fortran). AFAIK g95 все еще разрабатывается, хотя и медленнее, чем GFortran, но если ваша кодовая база чистая F77 / F95 и не использует передовые функции F2003 / F2008, возможно, стоит изучить? - person Tristan Brindle   schedule 15.10.2014C_NULL_CHAR
. - person Stefan   schedule 15.10.2014