2

我正在尝试从 C++ 访问 Fortran 公共块结构中的数组。
我有一个包含 C++ 和 Fortran 的混合示例代码。

Fortran:

integer a(5),b  
common  /sample/ a,b  
a(1) = 1  
a(2) = 5  
a(3) = 10  
a(4) = 15  
a(5) = 20  
b = 25  

然后在 C++ 中:

extern "C"{  
    extern struct{  
        int *a,b;  
}sample_;  

在 C++ 中,如果我尝试打印值sample_.b

printf("sample b:%d\n",sample_.b);

我得到 a(2) 的值:sample b:5

如果我尝试打印任何其他数组-a 值,我只会遇到分段错误......

printf("sample_.a[1]=%d\n",(int)sample_.a[1]);  
printf("sample_.a[0]=%d\n",(int)sample_.a[0]);

我做错了什么?¿任何想法¿?
我想,也许我也必须将数组“a”的长度传递给 C++,但如果是这样,我也不知道该怎么做。

4

5 回答 5

6

如果要在 C 和 Fortran 之间共享全局变量,最好的方法是使用模块变量和 Fortran ISO_C_Binding。公共块是遗物,除非是遗留代码的一部分,否则最好避免使用。使用 ISO_C_Binding 将使您的代码编译器和平台独立。gfortran 手册的“混合语言编程”一章的“可互操作全局变量”小节中有一个代码示例。这不是 gfortran 特有的,只是一些很好的文档。

继续使用 ISO_C_Binding,如果您使用它提供的 Fortran 类型,将确保您与 C 类型匹配。Fortran 等效于 C 的intC_INT。gfortran 手册的“内部模块”一章中有一个列表。

于 2012-05-07T22:32:15.397 回答
3

在我看来,您的 FORTRAN 数据实际上布局为

struct {
  int a[5];
  int b;
}

你在一台机器上sizeof(int) == sizeof(int*)

于 2012-05-07T13:03:56.240 回答
2

我的 Fortran 有点(好吧,有点)生锈,但让我试一试。

a可能收到 VALUE 而不是指向它的指针。这会将其设置为1,这不是一个好的指针值。

b接收到数据块中的第二个值。您的 C++ 结构没有向编译器指示数据的实际格式是什么,因此它只会按照结构中给出的顺序无意识地将项目分配给结构。我会得到一个指向数据块的指针并手动拆卸它。

分配a给数据块的地址(作为long int指针,看起来像;您的里程可能会有所不同)和b = a[5]. 希望有帮助。

于 2012-05-07T12:36:15.750 回答
0

谢谢大家的有用回答。按照您的建议,我终于意识到我的问题是什么。我认为我的错误是在 Fortran 中我有:

integer a(5),b  
common  /sample/ a,b  

a(5)具有固定大小,然后在 C++ 中:

extern "C"{  
    extern struct{  
        int *a,b;  
}sample_;  

*a没有大小,作为指针。因此,编译器将这种方式理解为*int指针而不是a(5)数组

于 2012-05-09T08:19:13.707 回答
0

对于正确的 C++/Fortran 代码,您至少应该使用 Fortran 2003。为旧的 Fortran 代码(甚至 Fortran 77)创建 Fortran 2003/2008 接口实际上非常简单。

这是一篇关于混合现代 Fortran 和 C++ 的帖子的链接:

http://solarianprogrammer.com/2012/05/11/mixed-language-programming-cpp-11-fortran-2008/

于 2012-05-11T16:43:17.833 回答