Я научился использовать глобальные переменные C в коде Fortran, как показано в примере ниже. Но как сделать это в обратном направлении, то есть определить (и инициализировать) переменную в Фортране и сделать ее доступной для C?

/* C global variables */

int c_extern;
long myVariable;

!Fortran binding code
MODULE LINK_TO_C_VARS
    USE ISO_C_BINDING
    !Implicit label binding
    !Bind variable C_EXTERN to c_extern
    INTEGER(C_INT), BIND(C) :: C_EXTERN

    !Explicit label binding
    !Bind C2 to myVariable
    INTEGER(C_LONG) :: C2
    BIND(C, NAME='myVariable') :: C2
END MODULE LINK_TO_C_VARS
3
Junchao Zhang 21 Мар 2014 в 22:02
2
Глобальная переменная, совместно используемая Фортраном и C, может быть изменена с помощью кода любого языка. Результирующее изменение отобразится в переменной, видимой для другого языка. Работает в обоих направлениях. Если у вас есть конкретная проблема, покажите весь соответствующий код.
 – 
M. S. B.
21 Мар 2014 в 22:10
1
Ваш код работает нормально, просто скомпилируйте его gcc -shared vars.c mod.f90 -o lib.so, и библиотека будет содержать эти переменные.
 – 
Vladimir F
21 Мар 2014 в 22:14
Будет ли этот оператор «INTEGER (C_INT), BIND (C) :: C_EXTERN» выделять переменную в сгенерированном объекте .o? Я не понимаю, кто выделяет память: C или Fortran.
 – 
Junchao Zhang
21 Мар 2014 в 22:18
1
Это не имеет значения. С ISO_C_BINDING Fortran «знает», что переменная Fortran такая же, как и переменная C. Для исполняемого файла зарезервировано только одно хранилище. Об этом позаботится совместимая пара компиляторов Fortran / C.
 – 
M. S. B.
21 Мар 2014 в 22:41
1
Небольшая поправка к последнему MSB - это BIND (C), который сообщает Fortran, что переменная должна взаимодействовать с C. Использование ISO_C_BINDING само по себе не имеет к этому никакого отношения.
 – 
Steve Lionel
24 Мар 2014 в 19:24

1 ответ

Лучший ответ

Следовать за:

Благодаря M.S.B.

Я провел несколько экспериментов. Я поместил код C в vars.c, код Fortran в mod.f90.

gcc -c vars.c
nm vars.o
0000000000000004 C c_extern
0000000000000008 C myVariable

gfortran -c mod.f90
nm mod.o
0000000000000004 C c_extern
0000000000000008 C myVariable

'man nm' говорит: "C" - это обычный символ. Общие символы - это неинициализированные данные. При связывании с одним именем может отображаться несколько общих символов. Если символ определен где-либо, общие символы рассматриваются как неопределенные ссылки.

Затем я изменил переменные в vars.c на extern

<<vars-ext.c>>
extern int c_extern;
extern long myVariable;

Gcc -c vars-ext.c и nm vars-ext.o

U c_extern
U myVariable

Gfortran может успешно связать mod.o с vars.o или vars-ext.o. Похоже, что волшебство кроется в символах типа "С".

0
Junchao Zhang 20 Авг 2014 в 17:53