'unlimited' function pointers? 
Author Message
 'unlimited' function pointers?

I have a component that acquires a C function pointer that I'd like to
convert to
a fortran procedure pointer while hiding the details of the process.
Something
like

subroutine dll_symbol (ffptr)
  procedure(), pointer :: ffptr
  type(c_funptr) :: cfptr
  ... code that acquires cfptr
  call c_f_procpointer(cfptr, ffptr)
end subroutine

And the caller would do something like

procedure(fun), pointer :: fp
call dll_symbol (fp)

This doesn't generally work, however, because of 'type' mismatch of
the
actual and dummy procedure pointer arguments.  It seems to care that
they are
both subroutines or both functions with the same return type, but
nothing about the arguments of the procedures.  What I'd like is for
dll_symbol to have a dummy procedure argument that is type compatible
with any procedure pointer -- something like an unlimited function
pointer.
Is there some way of doing this?

My current solution, of course, is to have dll_symbol return the bare
C function
pointer and require the user to do the conversion to the Fortran
procedure
pointer.

Thanks!
  Neil



Sun, 11 Sep 2011 22:38:20 GMT  
 'unlimited' function pointers?

Quote:
>I have a component that acquires a C function pointer that I'd like to
> convert to
> a Fortran procedure pointer while hiding the details of the process.
> Something
> like
> subroutine dll_symbol (ffptr)
>  procedure(), pointer :: ffptr
>  type(c_funptr) :: cfptr
>  ... code that acquires cfptr
>  call c_f_procpointer(cfptr, ffptr)
> end subroutine
> And the caller would do something like
> procedure(fun), pointer :: fp
> call dll_symbol (fp)
> This doesn't generally work, however, because of 'type' mismatch of
> the
> actual and dummy procedure pointer arguments.  It seems to care that
> they are
> both subroutines or both functions with the same return type, but
> nothing about the arguments of the procedures.  What I'd like is for
> dll_symbol to have a dummy procedure argument that is type compatible
> with any procedure pointer -- something like an unlimited function
> pointer.
> Is there some way of doing this?

There is sort of a way of doing this and I was trying to prepare an
example, but I hit the following roadblock:

C:\gfortran\clf\var_proc_ptr>type bug2.f90
module mytypes
   implicit none
   type type2
      real x
      real y
   end type type2
end module mytypes

module array_funcs
   use mytypes
   implicit none
   private
   public sub1, fun2, fun3
   contains
      subroutine sub1(x)
         real x(:)
         integer i

         write(*,'(a)') 'In subroutine sub1.'
         write(*,'(a)') 'x ='
         do  i = 1, size(x)
            write(*,*) x(i)
         end do
      end subroutine sub1

      function fun2(x,y)
         real x, y
         type(type2) fun2

         fun2%x = (x+y)/2
         fun2%y = sign(sqrt(abs(x*y)),x*y)
      end function fun2

      function fun3(x,y,n)
         real x, y
         integer n
         real fun3(n)
         integer i

         fun3 = x+([(i,i=1,n)]-1)*(y-x)/(n-1)
      end function fun3
end module array_funcs

module has_array
   use ISO_C_BINDING
   use array_funcs
   implicit none
   private
   public array, init_array
   type(C_FUNPTR), save :: array(3)
   contains
      subroutine init_array
         array(1) = init_array_helper(init_array_setter,sub1)
         array(2) = init_array_helper(init_array_setter,fun2)
         array(3) = init_array_helper(init_array_setter,fun3)
      end subroutine init_array

      function init_array_helper(x,y)
         use ISO_C_BINDING
         interface
            function x(y)
               use ISO_C_BINDING
               external y
               type(C_FUNPTR) x
            end function x
         end interface
         external y
         type(C_FUNPTR) init_array_helper

         init_array_helper = x(y)
      end function init_array_helper

      function init_array_setter(y)
         use ISO_C_BINDING
         implicit none
         type(C_FUNPTR), value :: y
         type(C_FUNPTR) init_array_setter

         init_array_setter = y
      end function init_array_setter
end module has_array

C:\gfortran\clf\var_proc_ptr>gfortran -c bug2.f90
bug2.f90:53.38:

         array(1) = init_array_helper(init_array_setter,sub1)
                                      1
Error: Type/rank mismatch in argument 'x' at (1)
bug2.f90:54.38:

         array(2) = init_array_helper(init_array_setter,fun2)
                                      1
Error: Type/rank mismatch in argument 'x' at (1)
bug2.f90:55.38:

         array(3) = init_array_helper(init_array_setter,fun3)
                                      1
Error: Type/rank mismatch in argument 'x' at (1)

I couldn't figure out how to work around this problem which I
think is a compiler bug so I gave up.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Mon, 12 Sep 2011 02:31:53 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Language question : function'Access / function'unchecked_Access

2. (documentation 'some-function 'function)

3. C++'s pointer vs Ada's Access type

4. Address of 'Lisp Pointers', perhaps Germany

5. Unlimited polymorphic pointers

6. function calls to external dll in 'routine's

7. CW2 Calling a 'C' Function

8. Prototyping 'C' Functions in Clairon

9. Bug in 'Build Array' function

10. MATLAB style 'sort' function

11. Rexx functions in 'C'

12. warning: overriding global function 'initialize'

 

 
Powered by phpBB® Forum Software