2

関係のない理由で、C/C++ 関数名を Fortran サブルーチンに渡す必要があります。Fortran サブルーチンは、その C 関数を呼び出します。私が見つけたのは、関数名を Fortran サブルーチンにうまく渡すことができるということです。そのサブルーチンで、正しい C 関数を呼び出すことができます。ただし、C 関数の引数はこの呼び出しで壊れます (C から直接呼び出された場合は問題なく動作します)。ISO C バインディングを使用して、これを機能させようとしましたが、役に立ちませんでした。

MWE は次のとおりです。

fortranRoutine.h:

extern "C" {
    void fortranRoutine_(void(int status));
};

呼び出されたFortran.h:

void calledfromFortran(int status);

main.cpp:

#include "fortranRoutine.h"
#include "calledfromFortran.h" 

using namespace std;

int main(int argc, char** argv) {
    calledfromFortran(12);
    fortranRoutine_(calledfromFortran);
    return 0;
}

fortranRoutine.f90:

subroutine fortranRoutine(calledfromFortran)

    use iso_c_binding

    implicit none

    interface
        subroutine calledfromFortran(status) bind (c)
            use iso_c_binding
            integer(kind = c_int), intent(in) :: status
        end subroutine calledfromFortran
    end interface

    integer(kind = c_int) :: one

    one = 2
    call calledfromFortran(one)
    return

end subroutine fortranRoutine

呼び出されたFortran.cpp:

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

using namespace std;

void calledfromFortran(int status) {
    cout << "In calledfromFortran:" << endl;
    cout << " status: " << status << endl;
}

現在の結果

これを実行すると、現在次のようになります。

In calledfromFortran:
 status: 12
In calledfromFortran:
 status: -1641758848

calledfromFortranfromへの最初の呼び出しはmain正しく機能しfortranRoutineますが、値から呼び出されると壊れます。実行するたびに、後者の値が変化することに注意してください。私は何を間違っていますか?

4

2 に答える 2

2

インターフェイス定義を read に変更します

interface
    subroutine calledfromFortran(status) bind (c)
        use iso_c_binding
        integer(kind = c_int), VALUE :: status
    end subroutine calledfromFortran
end interface

intent(in)が原因かわかりませんが、コードのその部分が正しくないようです。それを除けば、残りは(最初のパスでは)合理的で正しいように見えます。

ノート。ISO C バインディングは、FORTRAN 言語の 2003 リリースでのみ追加されたため、古いバージョンを使用している場合は、コンパイラのドキュメントで詳細を確認する価値があります。一部のコンパイラでは ISO C バインディングが許可されていますが、上記で示したものとは少し異なる方法で呼び出される場合があります。


編集。intentキーワードを調べた後、定義intent(in)に続く次の型宣言と組み合わせて使用​​してみてください。interface

integer (c_int), parameter :: one = 2

これが役立つことを願っています。

于 2013-01-23T17:17:56.883 に答える