【问题标题】:trying to call fortran subroutine in c++试图在 C++ 中调用 fortran 子例程
【发布时间】:2019-05-22 18:14:51
【问题描述】:

我对 C++ 的了解非常有限,对 fortran 的了解更少,我目前正在尝试从 c++ 主程序调用 fortran 子例程。按照一些示例,我能够想出以下代码来调用

subroutine fireballess(ear,ne,parames,ifl,photar,photer)

这是我的 C++ 代码:

#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace std;

extern "C" void fireballess_( double *fear, int fne,double* fparames, int fifl, double *fphotar, double *fphoter);

int main(int argc, char ** argv)
{
    int ne,ifl;
    double *ear;
    double *parames;

    double *photar;
    double *photer;


    parames = new double[9];

// parames=[4.3,0.23,0.5,0.5,1.5,1.,1000.,2.15,3.]
        parames[0]=4.3;
        parames[1]=0.23;
        parames[2]=0.5;
        parames[3]=0.5;
        parames[4]=1.5;
        parames[5]=1.;
        parames[6]=1000.;
        parames[7]=2.15;
        parames[8]=3.;

ne = 2;

    ear = new double[ne];
 ear[0] = 0.;
 ear[1] = 20.;
 ear[2] = 40.;
 ifl=2;

    photar = new double[ne];
    photer = new double[ne];

    // Call a Fortran subroutine
    //subroutine_sum_(&size,vec,&sum);
    fireballess_(&ear,ne,&parames,ifl,&photar,&photer);

    cout << "Calling a Fortran subroutine" << endl;
    cout << "===============================" << endl;

for (int i=0;i<=ne;i++){
    cout << "ear = " <<ear[i-1]<< " - "<<ear[i] << endl;
    cout << "photar = " << photar[i] << endl;
    cout << "photer = " << photer[i] << endl << endl;
}

    delete[] ear;
    delete[] parames;
    delete[] photar;
    delete[] photer;
}

但是,当我尝试编译时,出现以下错误:

call_fortran.cpp: In function ‘int main(int, char**)’:
call_fortran.cpp:45:53: error: cannot convert ‘double**’ to ‘double*’ for argument ‘1’ to ‘void fireballess_(double*, int, double*, int, double*, double)’
     fireballess_(&ear,ne,&parames,ifl,&photar,photer);

我不明白,因为 photer 变量遵循与 photar 变量完全相同的路径,因此不会出现错误。 我希望比我更了解指针的人可以在这里帮助我。 谢谢

【问题讨论】:

  • 如果您希望我们评论Fortran子程序对应的原型是否正确,请显示该子程序参数的声明。
  • ear 已经属于double * 类型,所以&amp;ear 属于double ** 类型,这与您的声明double *fear 不同
  • @francescalus 我想这就是你所指的:integer ne,iflreal*4 ear(0:ne),parames(10),photar(ne),photer(ne)
  • @BennyK 谢谢,消除了 & 与编译一起工作。现在我遇到了分段错误-.-"
  • 我还想补充一点,“ne”、“ifl”、“ear”、“parames”等非常接近命名空间std中包含的标识符,这就是为什么using namespace std;@987654321 @,因为 std 中的其他内容可能会影响代码中的标识符或其他方式。

标签: c++ fortran


【解决方案1】:

eardouble* 类型,因此 &amp;eardouble** 类型,这对于 fortran 函数原型是不合适的。摆脱&amp;s 可能解决问题(&parames, &photar 和 &photer 也是双**):

改变

fireballess_(&ear,ne,&parames,ifl,&photar,&photer);

fireballess_(ear,ne,parames,ifl,photar,photer);

fortran 函数原型似乎是void fireballess_(double*, int, double*, int, double*, double)。如果确实如此,那么photer 仍然必须更改为photer[i],其中(i 是一个数组索引,如 0、1、2...)。

如果你真的想了解发生了什么,我建议阅读一本好的 C++ 指针教程。

【讨论】:

  • 谢谢,正如您和 BennyK 指出的那样,这就是问题所在。我无法理解它,因为错误似乎只指向所涉及的变量之一。代码现在可以正确编译,即使我在运行时遇到分段错误 -.-"
  • 1.使用调试器运行它 2. 查看哪一行引发了段错误 3. 找出该行中的哪个访问恰好引发了段错误 4. 找出它是如何产生无效访问的。 或者更好: 根本不要使用原始指针。(在你的情况下,你可以使用 std::vector 或 std::array 代替)。
  • 对子例程的调用显然导致了分段错误,我发现它试图将其移动到 for 循环中:将代码从:fireballess_(ear,ne,parames,ifl,photar,photer); 更改为 cout &lt;&lt; "Calling a Fortran subroutine" &lt;&lt; endl; for (int i=0;i&lt;=ne;i++){ fireballess_(&amp;ear[i],ne,parames,ifl,&amp;photar[i],&amp;photer[i]); cout &lt;&lt; "ear = " &lt;&lt;ear[i-1]&lt;&lt; " - "&lt;&lt;ear[i] &lt;&lt; endl; cout &lt;&lt; "photar = " &lt;&lt; photar[i] &lt;&lt; endl; } 返回了一个工作代码到无火的召唤。稍后我会回去测试,谢谢
猜你喜欢
  • 2014-01-14
  • 2012-01-02
  • 1970-01-01
  • 2021-09-21
  • 2013-07-24
  • 2019-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多