加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Fortran-C函数指针在某些情况下导致C代码出现seg错误

发布时间:2020-12-16 07:08:05 所属栏目:百科 来源:网络整理
导读:我正在修改 fgsl所以我可以传递函数指针而不是函数的名称.为此,我使用Fortran绑定(c)函数,调用c_funloc,调用C函数并将其分配给派生类型(c_ptr).但是,C代码根据我实现代码的方式给出了段错误. C代码: #include stdio.h#include stdlib.hstruct function_stru
我正在修改 fgsl所以我可以传递函数指针而不是函数的名称.为此,我使用Fortran绑定(c)函数,调用c_funloc,调用C函数并将其分配给派生类型(c_ptr).但是,C代码根据我实现代码的方式给出了段错误.

C代码:

#include <stdio.h>
#include <stdlib.h>
struct function_struct 
{
  double (* function) (double x);
};

typedef struct function_struct gsl_function;

gsl_function *function_cinit(double (*func)(double x)) {

    gsl_function *result;

     if (func) {
      printf("Passed Function Not Nulln");
    }

    printf("The size of gsl_function is %zun",sizeof(gsl_function));
    result = (gsl_function *) malloc(sizeof(gsl_function));
    result->function = func;

    printf("Res: %fn",(*func)(2.0));

    if (result) {
      printf("Result Not Nulln");
    }

    return result;
}

现在我的主程序/模块:

module integral
  use,intrinsic :: iso_c_binding
  implicit none

  !Interface to call C function
  interface
     function function_cinit(func) bind(c)
       import
       type(c_funptr),value :: func
       type(c_ptr) :: function_cinit
     end function function_cinit
  end interface

 !Proc pointer interface for arbitrary math function f(x) which is passed to the C function so it can be used in a library that requires
 ! a pointer to a function
  abstract interface
     function rhox(r) bind(c)
       use,intrinsic :: iso_c_binding
       real(c_double),value :: r
       real(c_double) :: rhox
     end function rhox
  end interface

contains
  ! Arbitary function f(x) = x
  function f(x) bind(c)
    use,intrinsic :: iso_c_binding
    real(c_double) :: f
    real(c_double),value :: x
    f = x
  end function f

 !Function passed by name
  function func_init(func)
    interface
       function func(x) bind(c)
         use,intrinsic :: iso_c_binding
         real(c_double),value :: x
         real(c_double) :: func
       end function func
    end interface

    type(c_ptr) :: func_init
    type(c_funptr) :: fp

    fp = c_funloc(func)
    func_init = function_cinit(fp)
  end function func_init

  !Function passed with procedure pointer
  function fp_init(fun)
    procedure(rhox),pointer :: fun
    type(c_ptr) :: fp_init
    type(c_funptr) :: fp

    fp = c_funloc(fun)

    call c_f_procpointer(fp,fun)

    fp_init = function_cinit(fp)
  end function fp_init

  !C_funptr passed directly
  function cfun_ptr_init(fun)
    type(c_funptr) :: fun
    type(c_ptr) cfun_ptr_init

    cfun_ptr_init = function_cinit(fun)
  end function cfun_ptr_init


end module integral


program bsp
  use integral
  use,intrinsic :: iso_c_binding
  implicit none

  procedure(rhox),pointer :: fptr
  type(c_funptr) :: cptr
  type(c_ptr) :: c_result

  fptr => f

  cptr = c_funloc(fptr)


  call c_f_procpointer(cptr,fptr)

  !This works,calling the cptr after calling c_f_procpointer on c_funptr obtained by using c_funloc
  print *,"Evaluate C Function: ",fptr(2.0_c_double)
  print *,""

  !This Works f(2.0) = 2.0,valid pointer
  c_result = func_init(f)
  print *,"Passing Function Directly Successful"
  print *," "

  !This works,calling C function directly from main program passing it the c_funloc of the procedure8
  c_result = function_cinit(cptr)
  print *,"Calling C Function  Directly Successful"
  print *," "

  c_result = cfun_ptr_init(cptr)
  print *,"Calling C function by Passing c_funptr Successful"
  print *," "

  !Segmentation Fault 11,calling C function indirectly from function which I pass the Fortran Proc pointer
  c_result = fp_init(fptr)

end program bsp

解决方法

找到答案了!事实证明,我没有必要改变一个事情来允许代码接受程序指针.

!Function passed with procedure pointer
  function fp_init(fun)
    !Changed from:
    !procedure(rhox),pointer :: fun
    procedure(rhox):: fun
    type(c_ptr) :: fp_init
    type(c_funptr) :: fp

    fp = c_funloc(fun)

    call c_f_procpointer(fp,fun)

    fp_init = function_cinit(fp)
  end function fp_init

我从伪参数中删除了“指针”属性,现在它可以工作了.我不知道为什么会这样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读