简体   繁体   English

如何从通用块-全局结构别名重新设计Fortran和C ++混合语言库?

[英]How to re-engineer Fortran and C++ mixed-language library from common blocks - global struct aliasing?

I have a program that consists of mostly Fortran 77 with a C++ wrapper that reads and writes to a database. 我有一个程序,该程序主要由Fortran 77组成,该程序带有读取和写入数据库的C ++包装程序。 The two parts of the application share data by uses a feature that if you use a global C/C++ struct named like a Fortran common block. 应用程序的两部分通过使用以下功能共享数据:如果使用的全局C / C ++结构的名称类似于Fortran公共块,则该功能是共享的。 I'm pretty sure this aliasing approach to C++/Fortran integration 1) works for many compiler suites, 2) is *not8 standard. 我敢肯定,这种C ++ / Fortran集成的别名方法1)适用于许多编译器套件,2)是* not8标准。 I try to maintain my code so that it uses standard components as much as I can. 我尝试维护我的代码,以便它尽可能使用标准组件。 Also, this integration has proven to be brittle. 而且,这种集成已被证明是脆弱的。

In utd.h: 在utd.h中:

/*************************************************************
 *  This struct must follow the common block points.
 *  See the Fortran include file points.i
 *************************************************************/
typedef struct ALIGN points
{
    double  point[3][MAX_PTS];
    double  edge[3][MAX_PTS];
    double  edgenorm[3][MAX_PTS];
    double  edgerho[MAX_PTS];
    int     nfacets[MAX_PTS];
    double  facet1[3][MAX_PTS];
    double  facet2[3][MAX_PTS];
    double  gaussk[MAX_PTS];
    int     sbstin[MAX_PTS];
    int     coatin[MAX_PTS];
    int     sbstout[MAX_PTS];
    int     coatout[MAX_PTS];
    int     ncorners[MAX_PTS];
    double  cnrpoint[3][MAX_CNRS][MAX_PTS];
    int     ncnredgs[MAX_CNRS][MAX_PTS];
    double  cnredge[3][MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     cnrsbst[MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     cnrcoat[MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     npoints;
} POINTS;

extern POINTS  points_;

In utd.cpp: 在utd.cpp中:

POINTS  points_;

In points.i: 在points.i中:

  !  maxpnt  -  maximum number of points in a path.
  integer  maxpnt
  parameter ( maxpnt = 1000 )

  integer npoints, nfacets(maxpnt)
  integer ncorners(maxpnt), ncnredgs(maxpnt,maxcorners)
  integer sbstin(maxpnt), coatin(maxpnt)
  integer sbstout(maxpnt), coatout(maxpnt)
  double precision point(maxpnt,3)
  double precision edge(maxpnt,3), edgenorm(maxpnt,3)
  double precision edgerho(maxpnt)
  double precision facet1(maxpnt,3), facet2(maxpnt,3)
  double precision gaussk(maxpnt), cnrpoint(maxpnt,maxcorners,3)
  double precision cnredge(maxpnt,maxcorners,maxcnredges,3)
  integer cnrsbst(maxpnt,maxcorners,maxcnredges)
  integer cnrcoat(maxpnt,maxcorners,maxcnredges)

  common /points/ point, edge, edgenorm, edgerho,
 *                nfacets, facet1, facet2, gaussk,
 *                sbstin, coatin, sbstout, coatout,
 *                ncorners, cnrpoint, ncnredgs,
 *                cnredge, cnrsbst, cnrcoat,
 *                npoints

Is there a better way? 有没有更好的办法? I might like to convert the common blocks to modules. 我可能想将通用块转换为模块。 Then I'm sure this business of aliasing a common block with a global struct is out the window. 然后,我确定将通用块与全局结构混为一谈的事情已经过去了。 How you you construct a Fortran module from C++? 您如何用C ++构造Fortran模块? How do you read data from such a module? 您如何从这样的模块读取数据?

What is your advice about C++/Fortran integration? 您对C ++ / Fortran集成有何建议?

The ISO C Binding of Fortran 2003 makes interoperability of C and Fortran part of the Fortran language standard, and therefore compiler and platform portable. Fortran 2003的ISO C绑定使C和Fortran的互操作性成为Fortran语言标准的一部分,因此可以实现编译器和平台的可移植性。 If you only use features of C, most likely it will work in C++, though perhaps that is not absolutely guaranteed. 如果仅使用C的功能,则很可能它将在C ++中运行,尽管可能不能绝对保证。 You can mix Fortran 2003 and FORTRAN 77, either within a source file or by mixing routines written in the two versions of the languages. 您可以在源文件中混合Fortran 2003和FORTRAN 77,也可以混合使用两种语言版本编写的例程。 The ISO C Binding supports structures and module variables as global variables, so it can accomplish your goals. ISO C绑定支持将结构和模块变量作为全局变量,因此可以实现您的目标。 Both of these are shown in the Mixed Language Programming Chapter of the gfortran manual. 两者都在gfortran手册的“混合语言编程”一章中进行了显示。 (The ISO C Binding is not specific to gfortran, I'm citing that as a good document.) (ISO C绑定并非特定于gfortran,我认为这是一个很好的文档。)

Common blocks are also supported, but I agree with you, best avoided ... common blocks add on FORTRAN storage sequence and layout, which is unnecessary. 还支持通用块,但我同意你的看法,最好避免...通用块会增加FORTRAN的存储顺序和布局,这是不必要的。 I don't see any way around manually maintaining the C and Fortran "structures" to have equivalent declarations. 我看不到有任何办法可以手动维护C和Fortran“结构”以具有等效的声明。 If that is the reason for the brittleness you will just have to be careful (baring writing a program to write both from common instructions). 如果那是造成脆性的原因,则只需要小心即可(禁止编写程序来从通用指令中编写两者)。 One approach that would make it a little easier would be not to put the variables into a structure ... then getting a new variable wrong is less likely to effect the older variables and that might make noticing or debugging a mistake easier. 一种使它更容易一些的方法是不将变量放入结构中……然后使新变量出错将不太可能影响较旧的变量,并且可能使发现或调试错误更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM