2017-07-15 34 views
0

过程调用形式参数更实际我有一个关闭此具体和切合主题的问题,试图从libcurl的简单API从Fortran语言调用C: https://stackoverflow.com/questions/44891188/calling-libcurl-from-fortran-2008的Fortran 2008Ç互操作误差:在(1)

按照意见的建议,我仍然遇到了关于如何从Fortran中正确调用C指针和C函数的错误。

没有太多的代码在这里,但主要问题是警告:

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 

也引用此:

+3

你需要指定'CURL'类型的组件,以及参数:在Fortran语言,我们应该写他们卷曲功能。这些你需要从卷曲头获得。 –

回答

3

我只想澄清一下C间的可移植性出头:

  1. 要进行帧间类型的便携式你应该重新输入其定义在Fortran语言与keywork bind(c)例如:

    在C中定义的type_c类型为:

    struct { 
        int i; 
        double d 
    } type_c; 
    

    Fortran语言,我们应该把它写成:

    type ,bind(c) :: type_c 
        integer(c_int) :: i 
        real(c_double) :: d 
    end type 
    
  2. Fortran中有两种类型的程序:功能和子程序。 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