Ошибка взаимодействия с Fortran 2008 C: более актуально, чем формальные аргументы в вызове процедуры в (1)
У меня есть конкретный вопрос по теме, который был закрыт при попытке вызвать C из простого API libcurl из Фортрана: https://stackru.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
Также упоминается это:
1 ответ
Я хочу пояснить кое-что о взаимозависимости C:
Чтобы сделать тип межпортативным, вы должны перепечатать его определение на Фортране с помощью клавиш
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
- В Фортране есть два типа процедур: функции и подпрограммы. эквивалентом подпрограмм в C являются функции, объявленные с
void
(в C: это означает функцию, которая не возвращает значение). Таким образом, чтобы сделать процедуры C взаимно переносимыми, вы должны сначала взглянуть на их определения и решить, эквивалентна ли она функции Фортрана или подпрограмме. Чтобы сделать 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