Использование аргументов по умолчанию для указателей в 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 ++, это не работает. Следующий пример кода демонстрирует sutiation
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;
}
}
и Основная программа Фортрана
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
в этом случае. Итак, есть ли решение этой проблемы? Я что-то здесь упускаю? Я думаю, что использование аргументов по умолчанию в смешанном программировании не работает, как ожидалось, но мне нужно предложение на данный момент.
Как указано в комментариях, вы не можете иметь значения параметров по умолчанию в 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
атрибут в интерфейсе. Если вы не предоставите необязательный массив, вместо него будет передан нулевой указатель.
Также обратите внимание на value
приписать var
аргумент. Это необходимо, потому что функция C ++ принимает параметр по значению.
Примечание: это довольно недавнее дополнение TS стандарту Fortran 2008, но широко поддерживается.
Других решений пока нет …