我是新手,但需要从C语言中调用一些旧的Fortran77函数。如可能,我不想改变Fortran代码,我希望编写一个包装器来调用Fortran函数。我希望能得到一个简单的工作示例(在Linux上)。我的做法:
在somefunction.f文件中:
REAL*8 FUNCTION MYFUNC(ZZ)
IMPLICIT NONE
REAL*8 ZZ, T1
T1 = ZZ + 1.0D0
MYFUNC = T1
RETURN
END
使用gfortran -c somefunction.f -o somefunction.o
编译。
在debug.c文件中:
#include <stdio.h>
double cfunc(double x) {
double result = myfunc_( &x );
return result;
}
int main() {
double test = cfunc(3.0);
printf(" %.15f ",test);
}
通过gcc -c debug.c -o debug.o
进行编译。
然后我使用gcc debug.o somefunction.o
和./a.out
。
但是,我得到的是无意义的数字,而不是3+1=4。我该如何纠正这个问题?
P.S: 如果这个问题解决了,我实际使用的函数会更加复杂:
如果MYFUNC不再是类型为
COMPLEX*16 FUNCTION MYFUNC(ZZ)
且ZZ也是一个复数,我应该改变什么?如果MYFUNC调用某些内置的Fortran函数,比如CDLOG(ZZ),该怎么办?
如果它访问一个公共块,能否也适应这种情况?
real*8
是 Fortran 指定double
的方式。它[大致上]是“占用 8 字节的浮点数”。而且,在 Fortran 中,real*8
已经存在了几十年... - Craig Esteyreal*8
的代码]。使用real*8
比kind
早至少二十年。因此,每个需要保持相关性的可信Fortran编译器都将支持real*8
。而且,real*8 xs
比REAL(KIND=8) :: XS
更紧凑,因此由于需要/在任何地方使用的简洁性而获胜。此外,F2008允许使用REAL64
,这仍然更好。 - Craig Esteyiso_c_binding
模块:a)它定义了保证与其C对应类型匹配的数据类型(=不需要猜测real*8
是否真正是double
等),b)一个bind(c,name="foo")
函数在C中具有清晰定义的签名和符号名称(foo(...)
保证按预期工作)。简而言之,它使您脱离了模糊的实现定义行为领域,进入到了规范符合的C/fortran明确定义的领域。 - cmaster - reinstate monica