2016-02-20 3 views
1

У меня есть модуль, который содержит глобальные переменные. Чтобы объявить некоторые глобальные переменные, мне нужно использовать HDF5. Я также использую библиотеку, поэтому мне также нужно включить заголовочный файл. Таким образом, преамбула global_variable.F90 выглядит так.PETSC header # include'd в модуле

module global_variables 

use HDF5 
#include "finclude/petscsys.h" 
#include "finclude/petscvec.h" 

integer(HID_T) id_file 
integer(HID_T) id_plist 
Vec M, C, K 
... 

end module 

Vec представляет собой тип данных, определенный в заголовочном файле и HID_T это тип данных, определенный в модуле HDF5.

Теперь у меня есть файл, который содержит подпрограммы для ввода-вывода. Этот файл также использует HDF5 и ту же библиотеку, что и в global_variables.F90. Поэтому IO.F90 выглядит так.

module io 

use global_varibles 

contains 

subroutine read_input_file(vector) 

Vec vector 
integer HDF5err 

call H5open_f(HDF5err) 
... 

end subroutine 

end module 

Вопрос 1: компилятор возвращает ошибку при компиляции IO.F90, говоря, что Vec не определен тип данных. Но он не жалуется на HID_T. Я думал, что модуль global_variables уже содержит модули HDF5 и файлы заголовков, используя модуль global_variables в IO.F90 будет обрабатывать каждое объявление типа данных, но, похоже, это не так. Не могли бы вы помочь мне понять, что я понимаю неправильно?

Вопрос 2: Есть ли способ ограничить влияние #include на модуль, где он объявлен?

PS. Если я включу #include "finclude/petscvec.h" в IO.F90, который объявит Vec, тогда он хорошо компилируется.

+0

Как определяется 'vec'? Это макрос, скажем? – francescalus

+0

Это всего лишь C-указатель 'typedef struct _p_Vec * Vec;'. – user79973

+0

Извините за мое уродливое объяснение. Библиотека написана на языке C, а также предоставляет конвертер fortran. Я использую эту fortran-обертку как include-файлы. Я не знаю, что именно происходит внутри файлов заголовков. Он многократно вложен и, наконец, заканчивается «#define Vec PetscFortranAddr». Я не знаю, что это такое ** PetscFortranAddr **. – user79973

ответ

3

Синтаксис

Vec vector 

совершенно чужд Fortran. Он работает только потому, что Vec является C препроцессор (CPP) макрос, определенный в заголовочном файле «finclude/petscvec.h» как

#define Vec PetscFortranAddr 

Это означает, что необходимо включить файл заголовка в каждом Fortran файл, в котором вы используете приведенный выше синтаксис с Vec. Макрос не может быть наследован с использованием Fortran use, поскольку он не является частью Fortran.

PetscFortranAddr находится в конце определенного в «finclude/petscdef.h» как целое число с 4 или 8 байт в зависимости от системы.

Возможно, вы ничего не можете сделать, кроме обратного инжиниринга, что это, в конце концов, является предварительным процессором, но я не пошел бы таким путем, он может быть неспособен.

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