2017-06-27 8 views
3

コンパイルされない次のコードがあります。 FortranインターフェイスをC++でオーバーロードされた関数として呼び出すことは可能ですか?以下で試してみますか?C++からFortranインターフェイスを呼び出すことは可能ですか

これは、Fortranコードです:

module functions 
    use, intrinsic :: iso_c_binding, only : c_double, c_int 
    implicit none 

    interface increment bind(c, name="increment") 
     module procedure increment_int, increment_double 
    end interface 

contains 
    subroutine increment_int(a, b) 
     integer(c_int), intent(inout) :: a 
     integer(c_int), value :: b 

     a = a + b 
    end subroutine 

    subroutine increment_double(a, b) 
     real(c_double), intent(inout) :: a 
     real(c_double), value :: b 

     a = a + b 
    end subroutine 
end module functions 

そして、これはC++コードです:

#include <iostream> 

namespace 
{ 
    extern "C" void increment(int&, int); 
    extern "C" void increment(double&, double); 
} 

int main() 
{ 
    int a = 6; 
    const int b = 2; 

    double c = 6.; 
    const int d = 2.; 

    increment(a, b); 
    increment(c, d); 

    std::cout << "a = " << a << std::endl; 
    std::cout << "c = " << c << std::endl; 

    return 0; 
} 
+1

通常、オーバーロードはネームマングリングによって実装されます(これは実装の詳細であり、標準ではありません)。関数を 'extern" C "' 'として宣言すると、C++コンパイラにmangleという名前のC ABIを使用するように求められます。簡単な解決策は、関数に2つのわずかに異なる名前を使用することです。また、C ABIの参照を渡すことはおそらくうまくいかないでしょう。 –

+0

2つの名前のバージョンはすでに動作しています(参照渡しも含みます)。これを避けることができるのであれば私は興味がありました。 – Chiel

答えて

2

いいえ、それを回避することはできません。しかし、テンプレートをインスタンス化して2つを呼び出すことができます。または、これらの2つのextern C関数に対するC++汎用ラッパーを作成します。 Fortranにインターフェイスをエクスポートすることは間違いありません。インターフェースは、Fortranで内部的にある名前で2つのサブルーチンを呼び出す方法を説明したものです。

この質問importing interface module procedure from fortran into Cは非常に似ています。私はもともとあなたのコピーを複製として閉じていましたが、試行された解決策がわずかに異なるため、私は心を変えました。

しかし、原則は同じです。 FortranジェネリックスとC++ジェネリックは互換性がありません。そしてそれらの間にC型があり、同様のタイプのジェネリックはありません。

注:@リチャードクリートは、extern C関数で参照渡しをするべきではないことを示唆しています。コンパイラはおそらくそれをコンパイルし、ポインタを値渡しとして実装しますが、それは保証されません。ポインタを渡すだけです。詳細については、C++ by-reference argument and C linkageを参照してください。

関連する問題