在C++中尝试调用Fortran子程序

4
我对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 functionint 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子程序对应的原型是否正确,请显示该子程序参数的声明。 - francescalus
1
ear is already of type double *, so &ear is of type double **, which differs from your decleration double *fear - Benny K
@francescalus 我想这就是你所指的内容: 整数 ne,ifl 实数*4 ear(0:ne),parames(10),photar(ne),photer(ne) - J. Dowe
@BennyK 谢谢,去掉 & 后编译成功了。现在我遇到了分段错误 -.-" - J. Dowe
我还想补充一点,"ne"、"ifl"、"ear"、"parames"等等都与命名空间std中的标识符非常接近,这就是为什么通常应该避免使用using namespace std;的原因,因为否则std中的内容可能会掩盖您代码中的标识符,反之亦然。 - nada
1个回答

1

ear 的类型是 double*,所以 &ear 的类型是 double**,这对于 Fortran 函数原型来说不是可行的。去掉 & 可能会解决问题(&parames&photar&photer 也都是 double**):

更改为

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指出的那样,那就是问题所在。由于错误似乎只指向其中一个变量,我无法理解它。现在代码可以正确编译,即使在运行时出现分段错误-.-" - J. Dowe
  1. 使用调试器运行它
  2. 查看哪一行抛出了段错误
  3. 找出在该行中哪个访问导致了段错误
  4. 找出是如何导致无效访问的。或者更好的方法是: 根本不使用裸指针。(在您的情况下,您可以使用std::vector<double>或std::array<double, n>代替)。
- nada
调用子例程显然导致分段错误,我尝试将其移至for循环内部发现此问题:将代码从 fireballess_(ear,ne,parames,ifl,photar,photer); 改为 cout << "Calling a Fortran subroutine" << endl; for (int i=0;i<=ne;i++){ fireballess_(&ear[i],ne,parames,ifl,&photar[i],&photer[i]); cout << "ear = " <<ear[i-1]<< " - "<<ear[i] << endl; cout << "photar = " << photar[i] << endl; } 返回的是可工作的代码,但只能执行到fireballess函数调用。稍后我会回去测试,谢谢。 - J. Dowe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接