Символ Fortran отсутствует в таблице загрузки (невозможно вызвать загруженный символ в R)
Я пытаюсь создать библиотеку Fortran DLL с Absoft Pro Fortran 13.0.3, 64 бита, для использования в R, на Windows 7 64 бита.
Вот мой файл mycalc.f (это глупый пример, просто для проверки функциональности):
subroutine mycalcf(a,b,c)
real*8 a,b,c
dll_export mycalcf
c=a+b*b
end
Заявлениеdll_export
не является стандартным, но встречается в некоторых компиляторах Фортрана (AFAIK также встречается в Lahey и CVF, а в Intel Fortran вместо этого есть директива компилятора). Он просто сообщает компилятору, какие символы должны быть экспортированы.
Я успешно компилирую с:af90 -m64 -dll -YDLL_NAMES=LCS mycalc.f -o mycalc.dll
Опция-YDLL_NAMES=LCS
говорит компилятору собрать библиотеку со строчными символами, что кажется лучше для R.
Если я бегуdumpbin /exports mycalc.dll
Я могу найти mycalcf в экспортированных символах, в нижнем регистре, без подчеркивания до или после.
Теперь из R (64-битная версия) работает следующее:
dyn.load("mycalc.dll")
is.loaded("mycalcf")
.Fortran("mycalcf", a=4, b=5, c=0)
Я получаю с = 29 по возвращении, как и ожидалось.
НО, если я перезапустить R, следующее не работает (обратите внимание, я только удалилis.loaded
контрольная работа):
dyn.load("mycalc.dll")
.Fortran("mycalcf", a=4, b=5, c=0)
Я получаю ошибку:Fortran symbol name "mycalcf" not in load table
.
Теперь мой вопрос: почему этот тест так важен?
Для сравнения, когда я пытаюсь сделать то же самое с gfortran вместо Absoft, у меня нет никаких проблем. Я компилирую с:gfortran -m64 -shared -o mycalc2.dll mycalc.f
(после комментирования оператора dll_export, который не нужен и даже не распознан gfortran). Тогда в R:
dyn.load("mycalc2.dll")
.Fortran("mycalcf", a=4, b=5, c=0)
И я получаю с = 29, без ошибок.
Теперь я подозреваю, что линкер gcc делает что-то, что не выполняется автоматически компоновщиком Absoft (на самом деле это link.exe от Microsoft). Но я не имею ни малейшего намека на то, что это может быть.
Любая идея приветствуется!
Хорошо, решение после хорошего вопроса от Владимира Ф (см. Комментарии). На самом деле, нужно добавить подчеркивания к именам символов. Поскольку нет способа сделать это с помощью опции компилятора, нужноCDEC$
, директивы (см.HP или жеIntel документация).
Вот это просто:
subroutine mycalcf(a,b,c)
CDEC$ attributes alias:'mycalcf_' :: mycalcf
real*8 a,b,c
dll_export mycalcf
c=a+b*b
end
Второе решение, отАбсофт форум: на самом деле я был неправ с самого начала. Вопреки тому, что я думал, не нужно использовать оператор dll_export, и это даже создало проблему: без него компилятор добавляет подчеркивание. Все символы экспортируются по умолчанию, как в gfortran. Итак, правильный код просто:
subroutine mycalcf(a,b,c)
real*8 a,b,c
c=a+b*b
end
Нет даже необходимости в любой опции для получения строчных символов, это также значения по умолчанию.
Однако остается один вопрос: выполняет ли функция R.Fortran
всегда добавляйте подчеркивание (есть ли способ сказать, что нет?), и если оно всегда добавляется, почему вызов работает, когдаis.loaded
называется заранее? R, кажется, делает что-то странное здесь. Я пытался отследитьis.loaded
в исходном коде R (доdo_isloaded
вsrc\main\dotcode.c
), но безрезультатно.