Símbolo Fortran não está na tabela load (não é possível chamar o símbolo carregado em R)
Eu estou tentando construir uma DLL Fortran com o Fortran Absoft Pro 13.0.3, 64 bits, para uso em R, no Windows 7 64 bits.
Aqui está o meu arquivo mycalc.f (é um exemplo idiota, apenas para testar a funcionalidade):
subroutine mycalcf(a,b,c)
real*8 a,b,c
dll_export mycalcf
c=a+b*b
end
A declaraçãodll_export
não é padrão, mas é encontrado em alguns compiladores Fortran (AFAIK também é encontrado em Lahey e CVF e Intel Fortran tem uma diretiva de compilador). Apenas informa ao compilador quais símbolos devem ser exportados.
Eu compilo com sucesso com:af90 -m64 -dll -YDLL_NAMES=LCS mycalc.f -o mycalc.dll
A opção-YDLL_NAMES=LCS
diz ao compilador para construir uma biblioteca com símbolos minúsculos, o que parece melhor para R.
Se eu correrdumpbin /exports mycalc.dll
, Eu posso encontrar mycalcf em símbolos exportados, em letras minúsculas, sem qualquer sublinhado antes ou depois.
Agora, a partir de R (versão de 64 bits), os seguintes trabalhos:
dyn.load("mycalc.dll")
is.loaded("mycalcf")
.Fortran("mycalcf", a=4, b=5, c=0)
Eu recebo c = 29 no retorno, como esperado.
MAS, se eu reiniciar o R, o seguinte não funciona (aviso eu só removi ois.loaded
teste):
dyn.load("mycalc.dll")
.Fortran("mycalcf", a=4, b=5, c=0)
Eu recebo o erro:Fortran symbol name "mycalcf" not in load table
.
Agora minha pergunta é: por que esse teste é tão importante?
Para comparação, quando eu tento o mesmo com o gfortran ao invés do Absoft, não tenho nenhum problema. Eu compilo com:gfortran -m64 -shared -o mycalc2.dll mycalc.f
(depois de comentar a declaração dll_export, que não é necessária, nem mesmo reconhecida, por gfortran). Então em R:
dyn.load("mycalc2.dll")
.Fortran("mycalcf", a=4, b=5, c=0)
E eu recebo c = 29, sem erro.
Agora, eu suspeito que há algo que o link do gcc faz que não é feito automaticamente pelo vinculador Absoft (na verdade, é o link.exe da Microsoft). Mas não tenho a menor ideia do que pode ser.
Qualquer ideia é bem vinda!
Ok, solução depois de uma boa pergunta de Vladimir F (ver comentários). Na verdade, é preciso acrescentar sublinhados aos nomes dos símbolos. Como não há como fazer isso pela opção de compilador, é necessárioCDEC$
diretivas (verHP ouIntel documentação).
Aqui é simplesmente:
subroutine mycalcf(a,b,c)
CDEC$ attributes alias:'mycalcf_' :: mycalcf
real*8 a,b,c
dll_export mycalcf
c=a+b*b
end
Segunda solução, deFórum Absoft: na verdade eu estava errado desde o começo. Ao contrário do que eu pensava, não é necessário usar a instrução dll_export, e ela até introduziu o problema: sem ela, o compilador acrescenta sublinhados. Todos os símbolos são exportados por padrão, como em gfortran. Então o código correto é simplesmente:
subroutine mycalcf(a,b,c)
real*8 a,b,c
c=a+b*b
end
Não há necessidade de qualquer opção para obter símbolos minúsculos, é também o padrão.
No entanto, uma questão permanece: a função R.Fortran
sempre adicionar sublinhado (existe uma maneira de dizer que não?), e se é sempre adicionado, por que a chamada funciona quandois.loaded
é chamado de antemão? R parece estar fazendo algo estranho aqui. Eu tentei rastrearis.loaded
no código-fonte R (atédo_isloaded
emsrc\main\dotcode.c
), sem sucesso.