2016-04-06 4 views
3

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

и 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 

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

+0

Хотя ответ на вопрос не принят, я думаю, что он затрагивает вашу проблему, другими словами, вы не можете иметь функции не-C (такие как параметры по умолчанию) при компиляции/связывании с 'extern C'. Вот несколько способов имитации: http://stackoverflow.com/q/2988038/3093378 – vsoftco

+1

Использование extern «C» позволит компоновщику связать вызов myfunc (1) fortran с функцией с двумя аргументами. Но только 1 поставляется, большое время UB. Вы не можете этого сделать, используйте функцию с другим именем, например myfunc2(). –

+1

@vsoftco Я не согласен с дублированием этого. Проблема может быть решена, просто необязательная часть аргумента должна быть выполнена в Fortran, она поддерживает это. –

ответ

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 в интерфейсе. Если вы не предоставите дополнительный массив, вместо него будет передан нулевой указатель.

Также обратите внимание на атрибут value аргументу var. Это необходимо, потому что функция C++ принимает параметр по значению.

Примечание: это довольно недавнее дополнение, как TS к стандарту Fortran 2008, но широко поддерживается.

+0

спасибо за ваше решение. это поддерживается в g ++ и gfortran? вы его протестировали?я спрашиваю, потому что, когда я пытаюсь скомпилировать ваш код с командами, приведенными в моем первоначальном сообщении, он жалуется на функцию _myfunc (Неопределенные символы для архитектуры ...) и не компилируется. – epsilon

+0

@epsilon Да, это сработает. Noice, который я переименовал _myfunc в myfunc, и что я использую 'bind (C, name =" myfunc ")' Обязательно следуйте этим деталям или оставьте _myfunc и используйте 'bind (C, name =" _ myfunc ")'. –

+0

Да, я знаю, что имя функции изменилось. Это странно, и я использую ваш код без каких-либо изменений, но он не компилируется. Я ничего не менял в функции и основной программе. вы думаете, что может возникнуть проблема с версией компилятора. – epsilon

Смежные вопросы