Совместимость GNU Fortran и C

У меня есть большая, смешанная кодовая база C / Fortran, в настоящее время скомпилированная с использованием инструментов Intel для Windows. Меня попросили перенести его на инструменты GNU в Linux. Более или менее наугад я выбрал версию 4.8.

Когда функция C вызывается из Fortran, совместимость часто выглядит так:

// 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?

5

Решение

Чтобы устранить ошибку компоновщика, вы можете сделать это иначе. Использовать опцию компилятора Intel имена преобразовать внешние имена в строчные, чтобы они соответствовали стандартному варианту GNU Fortran. И преобразовать имя в в нижнем регистре тоже:

void printstr(char *str, size_t len) {...}

Лично я бы рекомендовал использовать -funderscoring и Intel /assume:underscore различать функции, предназначенные для взаимодействия.

// C code:
void printstr_(char *str, size_t len) {...}

!Fortran code:
program test
implicit none
call printstr("Hello, world.")
end
2

Другие решения


По вопросам рекламы [email protected]