3

C++ でのポインターのデフォルト引数の使用法は、次のコードで実証できます。

#include <iostream>

void myfunc_(int var, double* arr = 0) {
  if (arr == 0) {
    std::cout << "1 arg" << std::endl;
  } else {
    std::cout << "2 arg" << std::endl;
  }
}

int main() {
  myfunc(1);
  double *arr = new double[2];
  myfunc(1, arr);
}

この場合、プログラムの出力は

1 arg
2 arg

一方、オプションの引数を Fortran から C++ に渡そうとしても、うまくいきません。次のコード例は、状況を示しています

myfunc.cpp _

#include <iostream>

extern "C" void myfunc_(int var, double* arr = 0) {
  if (arr == 0) {
    std::cout << "1 arg" << std::endl;
  } else {
    std::cout << "2 arg" << std::endl;
  }
} 

およびFortran メインプログラム

program main
use iso_c_binding

real*8 :: arr(2)

call myfunc(1)
call myfunc(1, arr)
end program main

混合コード (Fortran と C++) は、次のコマンドを使用してエラーなしでコンパイルできます。

g++ -c myfunc.cpp
gfortran -o main.x myfunc.o main.f90 -lstdc++ -lc++ 

しかし、プログラムは印刷します

2 arg
2 arg

この場合。それで、この問題の解決策はありますか?ここで何かが足りないのですか?混合プログラミングでデフォルト引数を使用すると、期待どおりに機能しないと思いますが、この時点で提案が必要です。

4

1 に答える 1

2

コメントで指摘されているように、extern "C"関数にパラメーターのデフォルト値を設定することはできません。ただし、関数の Fortran インターフェイスにオプションの引数を指定して、希望どおりに呼び出すことができます。

#include <iostream>
extern "C" void myfunc(int var, double* arr) { //removed the = 0 and renamed to myfunc
  if (arr == 0) {
    std::cout << "1 arg" << std::endl;
  } else {
    std::cout << "2 arg" << std::endl;
  }
}

Fortran で、C(C++) 関数を記述するインターフェイスを作成します。

program main
use iso_c_binding

interface
  subroutine myfunc(var, arr) bind(C, name="myfunc")  
    use iso_c_binding
    integer(c_int), value :: var
    real(c_double), optional :: arr(*)
  end subroutine
end interface

!C_double comes from iso_c_binding
real(c_double):: arr(2)

call myfunc(1_c_int)
call myfunc(1_c_int, arr)
end program main

重要なのはoptional、インターフェイスの属性です。オプションの配列を指定しない場合は、代わりに null ポインターが渡されます。

引数のvalue属性にも注意してください。varC++ 関数はパラメーターを値で受け入れるため、これが必要です。

注: これは、Fortran 2008 標準へのTSとしてごく最近追加されたものですが、広くサポートされています。

于 2016-04-07T09:13:06.283 に答える