Аргументы по умолчанию для указателя в C ++ и смешанного программирования

Использование аргументов по умолчанию для указателей в 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

в этом случае. Итак, есть ли решение этой проблемы? Я что-то здесь упускаю? Я думаю, что использование аргументов по умолчанию в смешанном программировании не работает, как ожидалось, но мне нужно предложение на данный момент.

3

Решение

Как указано в комментариях, вы не можете иметь значения параметров по умолчанию в 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, но широко поддерживается.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]