4

I want to call a Fortran subroutine, which I don't want to recode and which takes a assumed-shape array as input, from a C++ file. However if I pass a pointer (to handle the call by reference situation) on my allocated C++ array to the Fortran subroutine the application segfaults.

C++-file

#include <cstdlib>

extern "C" {
    void __fma_MOD_printvector2(int**);
}

int main(int argc, char const *argv[])
{
    int *vectorB = (int *)malloc(5*sizeof(vectorB));
    for(int i = 0; i < 5; i++)
    {
        vectorB[i] = i+10;
    }
    __fma_MOD_printvector2(&vectorB);
    return 0
}

Fortran-file:

MODULE fma
IMPLICIT NONE
CONTAINS
    SUBROUTINE printVector2(a)
        INTEGER, DIMENSION(:), INTENT(IN) :: a
        INTEGER :: i

        DO i=1,size(a)
            WRITE(*,*) a(i)
        END DO
    END SUBROUTINE printVector2
END MODULE fma

Output:

          10
[1]    5080 segmentation fault (core dumped)  ./main.x

Any ideas where I'm wrong?

Jannek S.
  • 365
  • 3
  • 16
  • Assumed shape arrays are not interoperable. Looking for a duplicate. – Vladimir F Героям слава May 28 '18 at 20:59
  • `__fma_MOD_printvector2(&vectorB);` -- 1) You're passing the address of the pointer. Is that intentional? 2) `DO i=1,size(a)` -- Where does FORTRAN get the size information? Even in C++ you can't get the size information from a pointer. – PaulMcKenzie May 28 '18 at 21:07
  • @PaulMcKenzie Fortran gets the size because the array is NOT a pointer. It is all in the link to the duplicate. But you are right with the pointers on the C++ size, it should just be `int*` provided the Fortran part is changed to an interoperable array argument. – Vladimir F Героям слава May 28 '18 at 21:10

1 Answers1

2

There is no interoperable interface from c to a Fortran procedure with an argument that is an assumed shape array, like in your case.

(Actually, as @IanH said, there is. Check if your compiler implements ISO/IEC TS 29113:2012)

I suggest you passing info on the shape of the array to the procedure through another argument and use an automatic array inside the routine.

SUBROUTINE printVector2(n, a) BIND(C)
    USE :: ISO_C_BINDING
    INTEGER(c_int), INTENT(IN) :: n
    INTEGER(c_int), DIMENSION(n), INTENT(IN) :: a
    INTEGER :: i

    DO i=1,n
        WRITE(*,*) a(i)
    END DO
END SUBROUTINE printVector2
Rodrigo Rodrigues
  • 7,545
  • 1
  • 24
  • 36
  • How did yoy manage to answer a closed question? – Vladimir F Героям слава May 28 '18 at 21:52
  • BTW, I asked about that, because it is interesting (it is not against you) https://meta.stackoverflow.com/questions/368733/how-did-this-user-manage-to-answer-a-closed-question But please try to not answer duplicated questions, we normally close them instead. That's why I searched for the duplicate although the answer was obvious and I could have answered it immediately. – Vladimir F Героям слава May 28 '18 at 21:57
  • And that question was itself closed as duplicate of https://meta.stackoverflow.com/questions/252711/this-answer-was-posted-after-the-question-was-closed-how-is-that-possible :) – Vladimir F Героям слава May 28 '18 at 22:07
  • When I started writing the answer there was no flag. I suppose it was a concurrency issue. Sorry about that. – Rodrigo Rodrigues May 28 '18 at 22:12
  • 1
    Yes, that is the reason why the system let it finish it, your browser did not know about the closure. You are also quite new so it is hard to know which questions were and were not answered already, do not worry about it too much. I wrote a comment immediately after openig the question that I am looking for the duplicate, but if you could not see the flag it could be the same with the comment. – Vladimir F Героям слава May 28 '18 at 22:17
  • 1
    Given ISO/IEC TS 29113:2012 has been out for a while and Fortran 2018 is not far away, the first paragraph is a bit misleading. – IanH May 29 '18 at 10:36