3

私は本当にあなたの助けが必要です!締め切りが迫っており、仕事を終わらせるのに十分なだけのことを学ぼうとしています。単純な問題のように見える問題に対処してから 1 週間以上が経過しましたが、オンラインで解決策をうまく実装できていません。

簡単に言うと、F77 から C++ コードを呼び出す必要があります。g++ と gfortran でコンパイルしています。私はmakefileの完全な初心者です。これらのコードをそれぞれのプログラムの一部としてコンパイルすると、バグがなくなります (main() ではなく、C++ コードから関数を取得し、それを fortran コードで使用しようとしています)。これが私が持っているものです:

C++ コード:

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

extern"C" double ShtObFun(double x[], int &tp)
{
    return //double precision awesomeness
}

Fortran コード:

    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

Makefile (上記のファイルのみを表示):

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 ではなく fortran から C++ 関数を呼び出す, gcc を使用して fortran と c++ バイナリをリンクする, FORTRAN から C コードを呼び出す,クックブック - Fortran から C を呼び出す, YoLinux - C/C++ と Fortran を一緒に使用する

編集(最初の回答への回答):

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);
}

次のエラーが表示されます: エラー: 'extern' エラーの前に初期化子が必要です: '{' トークンの前に非修飾 ID が必要です

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);
}

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

コードはコンパイルされますが、得られる結果は「tp = 0 に達しました」ですが、Fortran コードで tp を 1 に初期化したため (整数 tp = 1)、「tp = 1 に達しました」と表示されるはずです。関数を次のように単純に宣言すると、同じ問題が発生します。

extern"C" double shtobfun_(double *x, int *tp)
{
     //cout, etc
}
4

2 に答える 2

9

宣言または別名

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

なので

extern"C" double shtobfun_(double x[], int &tp)

http://gcc.gnu.org/onlinedocs/gcc/Weak-Pragmas.htmlを参照してください

それがあなたの最初のステップです。2 番目のステップは、Fortran が参照について認識していないことを認識することです。さらに、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);
}
于 2013-08-28T15:18:56.030 に答える