Ошибка взаимодействия Fortran 2008 C: более актуальные, чем формальные аргументы при вызове процедуры в (1)

У меня есть этот конкретный вопрос по теме, который был закрыт при попытке вызвать C из простого API libcurl из Фортрана: https://stackoverflow.com/questions/44891188/calling-libcurl-from-fortran-2008

Следуя советам из комментариев, я все еще получаю ошибки о том, как правильно вызывать указатели C и функции C из Fortran.

Здесь не так много кода, но основные проблемы - это предупреждения:

dl2.f08:11.23:

  type, bind(C) :: CURL
                       1
Warning: Derived type 'curl' with BIND(C) attribute at (1) is empty, and may be inaccessible by the C companion processor
dl2.f08:14.27:

И ошибки:

  call curl_easy_setopt(curl, CURLOPT_URL_VAL, "http://example.com")
                                                                    1
Error: More actual than formal arguments in procedure call at (1)
dl2.f08:48.35:

Вот мой минимальный пример:

module fcurl
! This is the simple C code I am trying to call from Fortran
!
! CURL *curl = curl_easy_init();
! if(curl) {
!   CURLcode res;
!   curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
!   res = curl_easy_perform(curl);
!   curl_easy_cleanup(curl);
! }
  use, intrinsic ::  iso_c_binding
  implicit none
  type, bind(C) :: CURL
  end type CURL

  type, bind(C) :: CURLcode
  end type CURLcode

  type, bind(C) :: CURLOPT_URL
  end type CURLOPT_URL

  interface
     subroutine curl_easy_init()  bind(C, name="curl_easy_init")
     end subroutine curl_easy_init
  end interface

  interface
     subroutine curl_easy_setopt()  bind(C, name="curl_easy_setopt")  
     end subroutine curl_easy_setopt
  end interface

  interface
     subroutine curl_easy_perform()  bind(C, name="curl_easy_perform")  
     end subroutine curl_easy_perform
  end interface

  interface
     subroutine curl_easy_cleanup()  bind(C, name="curl_easy_cleanup")  
     end subroutine curl_easy_cleanup
  end interface  

end module fcurl

program mycurl
  use fcurl
  type(CURL) :: curl
  type(CURLcode) :: res
  type(CURLOPT_URL) :: CURLOPT_URL_VAL
  call curl_easy_init(curl)
  call curl_easy_setopt(curl, CURLOPT_URL_VAL, "http://example.com")
  call curl_easy_perform(res, curl)
  print *, res  
  call curl_easy_cleanup(curl)

end program mycurl

Также ссылался на это:


person Mittenchops    schedule 15.07.2017    source источник
comment
Вам нужно указать компоненты типа CURL, а также аргументы для функций curl. Это вам нужно получить из заголовков curl.   -  person Alexander Vogt    schedule 16.07.2017


Ответы (1)


Я просто хочу кое-что прояснить о совместимости с C:

  1. Чтобы сделать тип переносимым, вы должны повторно ввести его определение в Фортране с помощью клавиш bind(c), Пример:

    Тип type_c, определенный в C как:

    struct {
      int i;
      double d
    } type_c;
    

    в Фортране мы должны записать это как:

    type ,bind(c) :: type_c
      integer(c_int) :: i
      real(c_double) :: d
    end type
    
  2. В Фортране есть два типа процедур: функции и подпрограммы. эквивалентом подпрограмм в C являются функции, объявленные с void (в C: это означает функцию, которая не возвращает значение). Итак, чтобы сделать процедуры C взаимно переносимыми, вы должны сначала взглянуть на их определения и решить, эквивалентен ли он в функцию или подпрограмму Fortran.
  3. Чтобы сделать процедуры C совместимыми с Fortran, вы должны определить их с их аргументами, например:

    Функции fun1 и fun2 определены в C как:

    float fun1(int i);
    void fun2(double a, int *l);
    

    в Фортране мы должны записать их как:

    interface
      function fun1(i) bind(c)
        real(c_float) :: fun1
        integer(c_int), value :: i
      end function fun1
    end interface
    
    interface
      subroutine fun2(a,l) bind(c)
        real(c_double), value :: a
        integer(c_int) :: l
      end subroutine fun2
    end interface
    
person M. Chinoune    schedule 16.07.2017