2

I'm trying to call a global string variable which is defined in a Fortran subroutine, in C. the C code is Cfile.c:

#include <stdio.h>

typedef struct {
        int length;
        char* string;
} fstring;

extern fstring stringf_;
void fortfunc_();

int main() {
        fstring stringC = stringf_;
        stringC.string[stringC.length-1] = '\0';
        printf("%s \n",stringC.string);
        return 0;
}

and FORTRAN code is Ffile.f:

subroutine fortfunc()
  
        character*30 string
        common/stringF/ string
        string = 'this is a string in FROTRAN77'

return
end

it compiles with:

gcc -c Cfile.c
gfortran -c -std=legacy Ffile.f
gfortran -c file.out -std=legacy Cfile.o Ffile.o

but when running I get the segmentation fault. I do not understand when I'm violating the memory boundaries though.

My operating system is:

Linux ubuntu 4.15.0-39-generic #42-Ubuntu SMP Tue Oct 23 15:48:01 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

and my compilers are:

GNU Fortran (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

I would appreciate if you could help me know where is my mistake and how I can solve it? other solutions to define a global variable in Fortran and then calling it in C are also welcomed.

5
  • verify that stringC.length is valid (>0) before using it as index. Commented Dec 1, 2018 at 3:09
  • @Aganju good point. I had already figured out that the returns 0 and that causes the segfault. but the questions remains then how can I pass a string from FORTRAN to C. you see more examples here. Commented Dec 1, 2018 at 9:28
  • Even better learn how to spell Fortran and search for "pass a string from Fortran to C" Commented Dec 1, 2018 at 15:12
  • Hold on a second, generally speaking, local variables, unless static in C, don't have any scope outside of the function... In that sense, it would be a good idea to test the variable in the Fortran module, in a test module I think. See if you can print it there before trying to get it from the C function. Many thanks for the update! Commented Dec 1, 2018 at 17:30
  • Changing the code to "typedef struct { char string[ 30 ]; } fstring;" and "stringC.string[ 29 ] = '\0';" works on my computer (<-- I think the common block contains raw characters rather than the pointer to them) Commented Dec 1, 2018 at 20:18

1 Answer 1

2

Based on the comments I got here and on Reddit, I now have a code which works. The C code:

#include <stdio.h>

typedef struct {
    char s[30];
} fstring;

extern fstring stringf_;

int main() {
    fstring stringc = stringf_;
    stringc.s[29] = '\0';
    printf("%s\n",stringc.s);
    return 0;
}

and FORTRAN code:

        BLOCK DATA

                CHARACTER*30 S
                COMMON /STRINGF/ S
                DATA S /'this is a string in FROTRAN77'/

        end

The segfault was happening because the passed stringC.length value is zero. It means unlike the example I was following here when calling a string from the FORTRAN side it does not pass the length as an integer!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.