I am trying to store a external, dynamically-loaded subroutine pointer in a common block, and I am getting an error I don't understand. (Please try not to laugh at the fixed-column format. I have to use it for certain reasons.)
c module module pif abstract interface subroutine pvalue(n,m) implicit none integer n,m end subroutine end interface end module c subroutine subroutine invokeit use :: pif, only : pvalue implicit none common /called_sub_cb/ called_sub integer n, m procedure(pvalue), pointer :: called_sub n = 4 called_sub(n,m) write(*,*)'the value is',m end c program program caller use :: ifwin use :: ifport use, intrinsic :: iso_c_binding use :: pif, only : pvalue implicit none common /called_sub_cb/ called_sub integer(handle) :: callee_handle integer(c_intptr_t) :: callee_addr procedure(pvalue), pointer :: called_sub callee_handle = LoadLibrary("pvalue.dll"C) if (callee_handle .eq. 0) then stop "DLL not loaded" end if callee_addr = GetProcAddress(callee_handle,"PVALUE"C) if (callee_addr .eq. 0) then stop "callee function not found" end if call c_f_procpointer(transfer(callee_addr,c_null_funptr), & called_sub) call invokeit end
This is adapted from a solution to calling dynamically-loaded DLLs I saw on this very forum. When I compile it, I get the following error:
caller.f(64): error #6404: This name does not have a type, and must have an expl
icit type. [CALLED_SUB]
Strangely, the error does not occur when pvalue is a function--it only happens for subroutines. It also doesn't occur unless the pointer is declared inside a common block. (That is, if I get rid of invokeit, and just call the subroutine from inside the main program, it compiles just fine.)
I'm open to other solutions besides common blocks to access the pointers, as long as it's accessible from a separetely-compiled subroutine (and doesn't have to be inside the same module or something like that).