Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调用C++;来自Fortran(链接问题?)_C++_Linker_Makefile_Fortran - Fatal编程技术网

C++ 调用C++;来自Fortran(链接问题?)

C++ 调用C++;来自Fortran(链接问题?),c++,linker,makefile,fortran,C++,Linker,Makefile,Fortran,我真的需要你的帮助!我已经到了最后期限,我正在努力学习,以完成一些工作。现在我已经处理了一个多星期了,这似乎是一个简单的问题,但我还没有能够成功地在线实施解决方案 长篇短文:我需要从F77调用C++代码。我正在使用g++和gfortran进行编译。我是一个制作文件的新手。当这些代码作为它们各自程序的一部分编译时,它们是无bug的(我从C++代码中获取函数,而不是主程序),并试图用FORTRAN代码使用它。以下是我得到的: C++代码: #include <cmath> #includ

我真的需要你的帮助!我已经到了最后期限,我正在努力学习,以完成一些工作。现在我已经处理了一个多星期了,这似乎是一个简单的问题,但我还没有能够成功地在线实施解决方案

长篇短文:我需要从F77调用C++代码。我正在使用g++和gfortran进行编译。我是一个制作文件的新手。当这些代码作为它们各自程序的一部分编译时,它们是无bug的(我从C++代码中获取函数,而不是主程序),并试图用FORTRAN代码使用它。以下是我得到的:

C++代码:

#include <cmath>
#include <vector>
using namespace std;

extern"C" double ShtObFun(double x[], int &tp)
{
    return //double precision awesomeness
}
    subroutine objfun(nv, var, f, impass)
    implicit real(8) (a-h,o-z), integer (i-n)
c   initializations including tp, used below

    f = ShtObFun(var, tp)

    return
    end
all:
    g++ -c Objective_Functions.cpp
    gfortran -c -O3 opcase1.f
    gfortran opcase1.o Objective_Functions.o -fbounds-check -lstdc++ -g -o Program.out
    rm *.o
opcase1.o: In function 'objfun_':
opcase1.f:(.text+0xbd): undefined reference to 'shtobfun_'
collect2: ld returned 1 exit status
Makefile(仅显示上面列出的文件):

#include <cmath>
#include <vector>
using namespace std;

extern"C" double ShtObFun(double x[], int &tp)
{
    return //double precision awesomeness
}
    subroutine objfun(nv, var, f, impass)
    implicit real(8) (a-h,o-z), integer (i-n)
c   initializations including tp, used below

    f = ShtObFun(var, tp)

    return
    end
all:
    g++ -c Objective_Functions.cpp
    gfortran -c -O3 opcase1.f
    gfortran opcase1.o Objective_Functions.o -fbounds-check -lstdc++ -g -o Program.out
    rm *.o
opcase1.o: In function 'objfun_':
opcase1.f:(.text+0xbd): undefined reference to 'shtobfun_'
collect2: ld returned 1 exit status
错误:

#include <cmath>
#include <vector>
using namespace std;

extern"C" double ShtObFun(double x[], int &tp)
{
    return //double precision awesomeness
}
    subroutine objfun(nv, var, f, impass)
    implicit real(8) (a-h,o-z), integer (i-n)
c   initializations including tp, used below

    f = ShtObFun(var, tp)

    return
    end
all:
    g++ -c Objective_Functions.cpp
    gfortran -c -O3 opcase1.f
    gfortran opcase1.o Objective_Functions.o -fbounds-check -lstdc++ -g -o Program.out
    rm *.o
opcase1.o: In function 'objfun_':
opcase1.f:(.text+0xbd): undefined reference to 'shtobfun_'
collect2: ld returned 1 exit status
我尝试过其他各种方法,但都不起作用。如果有人要求,我可以稍后再列出。有人看到这个问题了吗

我检查过的网站:

,, ,

编辑(对第一个答案的回应):

#include <cmath>
#include <vector>
using namespace std;

extern"C" double ShtObFun(double x[], int &tp)
{
    return //double precision awesomeness
}
    subroutine objfun(nv, var, f, impass)
    implicit real(8) (a-h,o-z), integer (i-n)
c   initializations including tp, used below

    f = ShtObFun(var, tp)

    return
    end
all:
    g++ -c Objective_Functions.cpp
    gfortran -c -O3 opcase1.f
    gfortran opcase1.o Objective_Functions.o -fbounds-check -lstdc++ -g -o Program.out
    rm *.o
opcase1.o: In function 'objfun_':
opcase1.f:(.text+0xbd): undefined reference to 'shtobfun_'
collect2: ld returned 1 exit status
<如果我改写C++代码为:

#include <cmath>
#include <vector>
using namespace std;

double ShtObFun(double x[], int &tp)
extern"C" double shtobfun_(double *x, int *tp) {
    return ShtObFun(x, *tp);
}
{
    cout << "reached tp = " << tp << endl;
    exit(1);
}
#include <cmath>
#include <vector>
using namespace std;

double ShtObFun(double x[], int &tp);

extern"C" double shtobfun_(double *x, int *tp) {
    return ShtObFun(x, *tp);
}

double ShtObFun(double x[], int &tp)
{
    cout << "reached tp = " << tp << endl;
    exit(1);
}
声明或别名

extern"C" double ShtObFun(double x[], int &tp)
作为

这是你的第一步。第二步是认识到Fortran不知道引用,而且它将所有参数作为指针传递。因此,您的F77接口应声明为:

extern"C" double shtobfun_(double x[], int *tp);
总而言之:

double ShtObFun(double x[], int &tp)
extern"C" double shtobfun_(double *x, int *tp) {
    return ShtObFun(x, *tp);
}

我建议使用Fortran 2003功能与C进行互操作,如下所述:

Fortran接口将如下所示:

      interface
         function shtobfun(x,tp) bind(C, name="ShtObFun")
           use iso_c_binding, only: c_double, c_int
           real(c_double) :: shtobfun
           real(c_double) :: x(*)
           integer(c_int) :: tp
         end function shtobfun
      end interface
对于大多数当前的编译器来说,这应该没问题,即使例程的其余部分是Fortran 77风格的(只要您对固定/自由格式源代码保持一致)。使用<代码>绑定(C)< /C> >允许您避免更改C++代码来处理CAPS和下划线。

编辑:

下面的子例程是使用gfortran和-ffix格式为我编译的。通过在最顶端添加
iso_c_binding
,我确保了此函数中隐式声明的任何内容都是c兼容的double或int,这可能是您想要的,也可能不是您想要的

然而,首先使用隐式声明是一个非常糟糕的主意。您应该真正使用
implicit none
,并显式声明您使用的每个变量

      subroutine objfun(nv, var, f, impass)
      use iso_c_binding, only: c_double, c_int
      implicit real(c_double) (a-h,o-z), integer(c_int) (i-n)
      interface
         function shtobfun(x,tp) bind(C, name="ShtObFun")
           import :: c_double, c_int
           real(c_double) :: shtobfun
           real(c_double) :: x(*)
           integer(c_int) :: tp
         end function shtobfun
      end interface

      dimension :: var(1)
      integer(c_int) :: tp

      f = ShtObFun(var, tp)

      return
      end

还有一件事:注意
var
必须是一个数组;我不知道它的实际尺寸,所以在这个例子中我只是把它的尺寸设为1。但是,它可以是任何级别。

漂亮!我以前试过类似的方法,但我想我没有正确地控制我的编程实验。一次发生的虫子太多了。非常感谢。实际上,我还有一个后续问题@Anycorn:我试着用你最后的建议替换我的行“extern”C“double ShtObFun(double x[],int&tp)”,但它没有编译。你能重新表述一下这应该如何实施吗?还有,为什么你有ShtObFun(x,*tp);在extern函数声明中?我认为@Anycorn关于引用是不正确的;在C++中引用引用的外部“C”函数与C函数的接口相同,它使用指针。@ EricInclan小心地将整数类型从f77传递到C++,反之亦然,您的f77类型可以很容易地被8字节。通过gdb运行程序并打印值和类型。@SeanPatrickSantos CMake在这方面对我很有帮助,FortranceInterfaceThanks提供了反馈。你能评论一下这个代码应该放在哪里吗?它是在“子程序objfun(nv、var、f、ALARM)”的内部还是上面?我在上面尝试过,但编译器没有接受它(gfortran)。例如,如果我将它放在子例程之上,编译器会说子例程声明是不可分类的语句。如果我把它放在子例程中,每一行都会变成“意外接口语句”或“不可分类语句”。再次感谢你的帮助!正确的位置在声明部分,即“隐式”之后和任何可执行语句之前。另外,我无意中把它变成了一个子程序,而不是一个函数;我将编辑我的答案来解决这个问题。这太棒了!再次感谢您对我们的帮助!