Когда вы используете .C
для вызова подпрограммы Fortran, вызывающий обрабатывает символьные аргументы как стиль C char **
. Это несовместимо с фиктивным аргументом Fortran типа character(len=255)
.
. У вас есть два «простых» подхода:
- изменить подпрограмму Fortran, чтобы принимать аргументы, похожие на
char **
- используйте
.Fortran
вместо .C
Изменение подпрограммы Fortran для использования совместимости C с char **
лучше предмет нового вопроса (для его широты ине является специфическим для вашей проблемы R). В общем, я предпочитаю писать процедуры на Фортране, которые будут использоваться в R как раскрывающие совместимый интерфейс C и .C
или .Call
. С этим можно также прийти к такому выводу.
Даже в документации на R нет оптимизма относительно передачи символьных аргументов с .Fortran
:
'. Fortran' пропускает первый (только) символьная строка символьного вектора в виде массива символов C для Fortran: это может быть использовано как 'символ * 255', если его истинная длина передается отдельно. Только до 255 символов строки передаются обратно. (Насколько хорошо это работает, и даже если оно вообще работает, зависит от компиляторов C и Fortran и платформы.)
Вам необходимо прочитать документацию о соглашениях о передаче аргументов, например для gfortran (обратитесь к соответствующей версии, поскольку эти условные обозначения могут измениться).
С .Fortran
и gfortran, тогда с процедурой, которая не совместима с C, вам нужно будет пройти "скрытый"msgstr "аргумент к процедуре Фортрана, указывающий длину символьного аргумента. Это верно для символов явной длины (постоянной длины, даже длины-1 или нет) и символов предполагаемой длины.
Для gfortran до версии 7 этот скрытый аргумент имеет целочисленное значение (R). Используя pow
вопроса или с аргументом предполагаемой длины, мы можем попробовать что-то вроде
bar <- .Fortran("pow", as.character("c"), as.double(x), as.double(0.0), 255L)
Заметьте, однако, что это не стандартно и по своей природе не переносимо. Действительно, как отмечают комментарии janneb и документация, связанная выше, то, как вы передадите этот скрытый аргумент из R в скомпилированную gfortran процедуру, зависит от версии gfortran, используемой . Использование 255L
в конце, вероятно, не сработает после gfortran 7. Вместо этого вам нужно будет передать скрытый аргумент как нечто, совпадающее с integer(c_size_t)
(возможно, 64-битным целым числом). Для компиляторов, отличных от gfortran, вам может потребоваться сделать что-то совсем другое.
На самом деле лучше использовать C-совместимую процедуру с аргументом, взаимодействующим с char **
(используя .C
) или char []
(используя .Fortran
). Как я уже сказал, здесь стоит остановиться на первом варианте, так как он оставляет больше гибкости (например, более длинные символы, больше переносимости и больше символьных аргументов).