Как вызвать функцию С++ из Fortran 77, используя std::vector в качестве аргументов?

Мне нужно заменить некоторые подпрограммы Fortran функциями C++. Поскольку литературы мало, я столкнулся с проблемой, подобной следующей.

Мой код всегда выдает ошибку:

Программа получила сигнал SIGSEGV: ошибка сегментации — неверная ссылка на память.

Это мой код на Фортране:

  PROGRAM vector_adder
  IMPLICIT NONE

  INTEGER,DIMENSION(3) :: a,b,c
  INTEGER :: i

  !C fill vectors with values
  DO i = 1,3
      a(i) = i
      b(i) = i
  END DO

  CALL ADD_VECTORS(a,b,c)

  WRITE(*,'(I5,I5,I5)') (c(i),i =1,3)

  STOP
  END PROGRAM

Рабочий код C:

void add_vectors_(int (*a)[3], int (*b)[3], int (*c)[3])
{
    for(int i = 0; i<3 ; i++)
    {
        (*c)[i] =(*a)[i] + (*b)[i];
    }
}

И я хотел бы аналогичный на C++:

extern "C" void add_vectors_(std::vector<int> *a, std::vector<int> *b, std::vector<int> *c)
{
    for(int i = 0; i<a->size() ; i++)
    {
        (*c)[i] =(*a)[i] + (*b)[i];
    }
}

person user615344    schedule 06.06.2017    source источник
comment
Также будет проще придерживаться вызова функции в стиле C в C++. Я не думаю, что существует портативный интерфейс для взаимодействия с объектом std::vector из FORTRAN.   -  person R Sahu    schedule 07.06.2017
comment
В более общем случае вы не можете передать объект C++ в Fortran, независимо от того, какой это класс C++. std::vector<int> не является особенным в этом смысле.   -  person Brick    schedule 07.06.2017
comment
Вы можете передать указатель на что угодно, будь то класс C++ или нет.   -  person Vladimir F    schedule 07.06.2017
comment
ISO_C_BINDING в фортране означает, что легче использовать смешанный код языка. Если версия на фортране работает, то переписывать ее на C не представляется оптимальным подходом.   -  person Holmz    schedule 07.06.2017


Ответы (2)


Вы смешиваете свой fortran, C жаргон vector, который относится к набору int в непрерывной ячейке памяти, то есть array с std::vector C++. std::vector – это отдельный класс контейнеров, который требует создания. См. документацию.

person Zakir    schedule 06.06.2017

Вот код C++, который вы можете вызвать из FORTRAN

extern "C" void add_vectors_(int(*a)[3], int(*b)[3], int(*c)[3])
{
    for (size_t i = 0; i<3; i++)
    {
        (*c)[i] = (*a)[i] + (*b)[i];
    }
}

std::vector<> не имеет переносимого интерфейса, позволяющего вызывать его из другого кода, отличного от C++; поскольку это шаблон, сделать это будет сложно. (На самом деле могут быть проблемы с std::vector совместимостью между разными версиями компилятора или разными компиляторами в одной и той же системе.)

Вам может понравиться что-то похожее на string_view C++17 для vector<>, но такое вещь не является частью стандартной библиотеки. Обратите внимание, что многие подпрограммы стандартной библиотеки принимают аргументы begin и end, которые хорошо работают с кодом в стиле C.

person Ðаn    schedule 06.06.2017