Функция интерфейса C со структурами в Fortran

Я хочу связать C-функцию с соответствующей структурой на Фортране

struct ovf_file {
    bool found;
    bool is_ovf;
    int n_segments;
    struct ovf_file_handle *_file_handle;
};
DLLEXPORT struct ovf_file * ovf_open(const char *filename);

Это моя попытка сделать это:

module ovf
    use, intrinsic :: iso_c_binding
    implicit none

    type, bind(c) :: ovf_file
      logical(c_bool)   :: found
      logical(c_bool)   :: is_ovf
      integer(c_int)    :: n_segments
      type(c_ptr)       :: file_handle
    end type ovf_file
end module ovf

program main
    use ovf
    use, intrinsic :: iso_c_binding
    implicit none
    type(ovf_file)               :: file_handle

    interface
      function ovf_open(filename) bind ( C, name = "ovf_open" ) result(handle)
        character(len=1, kind=c_char), intent(in) :: filename
        type(ovf_file)                            :: handle
      end function ovf_open
    end interface

    file_handle = ovf_open("testfile.ovf"//C_NULL_CHAR)
end program main

Это то, что я обычно делаю для интерфейса C, но gfortran (или ifort) не скомпилирует этот код (я даже не пытался связать его с двоичным файлом C). Вот вывод компилятора:

gfortran -c src/fortran_wrapper.f90                                                                                                                                                               [±master ●●]
src/fortran_wrapper.f90:22:30:

         character(len=1, kind=c_char), intent(in) :: filename
                              1
Error: Parameter ‘c_char’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
src/fortran_wrapper.f90:23:22:

         type(ovf_file)                            :: handle
                      1
Error: Derived type ‘ovf_file’ at (1) is being used before it is defined
src/fortran_wrapper.f90:30:12:

     ulala = ovf_open("testfile.ovf"//C_NULL_CHAR)
            1
Error: Type mismatch in argument ‘filename’ at (1); passed CHARACTER(1) to REAL(4)
src/fortran_wrapper.f90:30:12:

     ulala = ovf_open("testfile.ovf"//C_NULL_CHAR)
            1
Error: Can't convert REAL(4) to TYPE(ovf_file) at (1)

Почему он знает C-типы в модуле, но не в программе, хотя у меня такой же use-clause? Почему он не может найти тип, хотя я включаю модуль?

Я могу найти только очень простые варианты использования C-interoperability. Нет, которые объясняют структуры или C-строки. Как мне это сделать правильно?


person Stein    schedule 25.06.2018    source источник


Ответы (1)


Вы должны повторить «использовать iso_c_binding» в интерфейсе (сразу после функции ovf…)

Или вы можете импортировать символы C. Жаль, но интерфейсы не знают используемых модулей.

person Francois Jacq    schedule 25.06.2018
comment
Ты прав. Мне также пришлось добавить use ovf в интерфейс, и тогда это сработало. Спасибо - person Stein; 25.06.2018