【发布时间】:2019-08-16 21:38:54
【问题描述】:
我正在尝试在 C 中定义和声明一组结构,然后在 fortran 中与它们进行交互,然后再将它们传递回去以在 C 函数中进行操作。我知道可以通过使用 c 结构和 fortran 通用块来实现互操作性。我尝试了几种方法都没有成功。
限制:使用 cvfortran、f77。转换为较新的格式是不现实的。对于 C,使用 MSVS C 编译器。
这是 cvfortran 手册第 618 页的建议: (http://jp.xlsoft.com/documents/intel/cvf/cvf_pg.pdf)
“举个例子,假设你的 Fortran 代码有一个公共块,名为真的, 如图:"
!DEC$ ATTRIBUTES ALIAS:'Really' :: Really
REAL(4) x, y, z(6)
REAL(8) ydbl
COMMON / Really / x, y, z(6), ydbl
"您可以使用以下外部代码从您的 C 代码中访问此数据结构 数据结构:"
#pragma pack(2)
extern struct {
float x, y, z[6];
double ydbl;
} Really;
#pragma pack()
每当我尝试这个时,我都会收到“未解析的外部符号 _Really 在函数 xxx 中引用,并且无法编译。
CVFortran 手册中的方法:
Fortran
PROGRAM MYPROG
!DEC$ ATTRIBUTES ALIAS:'Really' :: Really
REAL(4) x, y, z
COMMON / Really / x, y, z
INTERFACE
SUBROUTINE STRUCTFUN()
cDEC$ ATTRIBUTES C, ALIAS:'_StructFun' :: STRUCTFUN ! for calling C functions
END SUBROUTINE STRUCTFUN
END INTERFACE
X = 6.
Y = 5.
Z = 0.
CALL STRUCTFUN()
END PROGRAM
C
#include <stdio.h>
void StructFun(void)
{
#pragma pack(2)
extern struct {
float x, y, z;
} Really;
#pragma pack()
printf("x: %f\n y: %f\n z: %f\n", Really.x, Really.y, Really.z);
printf("From C \n");
}
然后我尝试了我在下面粘贴的内容,其中我在头文件中定义了一个结构类型,然后尝试将其设置为 c 外部。我还应该提到,我将 C 函数导出为带有 .def 文件的 dll,以便可以从我的 fortran 模块中调用它。这不会产生任何错误,但会为我的所有变量返回零值。
示例程序:
Fortran
PROGRAM MYPROG
REAL(4) X,Y,Z
COMMON / REALLY / X, Y, Z
INTERFACE
SUBROUTINE STRUCTFUN()
cDEC$ ATTRIBUTES C, ALIAS:'_StructFun' :: STRUCTFUN ! for calling C functions
END SUBROUTINE STRUCTFUN
END INTERFACE
X = 6.
Y = 5.
Z = 0.
CALL STRUCTFUN()
END PROGRAM
C 函数
#include "structProg.h"
rtype really_;
void StructFun(void)
{
printf("x: %f\n y: %f\n z: %f\n", really_.x, really_.y, really_.z);
printf("From C \n");
}
C 头文件
#include <string.h>
#include <stdio.h>
typedef struct{
float x;
float y;
float z;
} rtype;
extern rtype really_;
extern void StructFun(void);
我知道问这个问题有点牵强,因为我使用的是旧编译器,但我们将不胜感激。
我也试过这里列出的方法:http://www.yolinux.com/TUTORIALS/LinuxTutorialMixingFortranAndC.html
【问题讨论】:
-
您报告的错误消息似乎与您提供的代码不一致。特别是,它抱怨的外部符号是
_Really,但您的代码都没有引用或访问这样的符号。此外,虽然您的 C 代码访问 similar 符号really_,但它也提供了该符号的定义,因此不应产生此类错误。我们将竭尽全力帮助您使用您正在使用的旧的且有些特殊的工具链,因此您比平常更重要的是提供一个实际证明问题的minimal reproducible example。 -
我将编辑第一个示例的示例,对此感到抱歉。
-
您的代码不符合 FORTRAN 77。
REAL(4)是 Fortran 90 语法,数字 4 与REAL*4中的 4 不同 stackoverflow.com/questions/838310/fortran-90-kind-parameterINTERFACE关键字也是 Fortran 90+。 -
我不确定第一条评论,但谷歌快速搜索显示了 F77 使用 INTERFACE 块的示例。更改类型投诉后,我得到了相同的结果。
-
您的意思是“对您来说看起来像 F77 的程序”... INTERFACE 绝对是 Fortran 90。您可以查看标签页上链接的标准 stackoverflow.com/tags/fortran/info Compaq Visual Fotran 确实支持 Fortran 90 和文件扩展名 .f 或 .f90 对此根本不重要,它只控制 fiexd 与免费源形式。
标签: c struct fortran language-interoperability fortran-common-block