Calling a dll routine from a subroutine different from the one in which the dll was loaded.

Calling a dll routine from a subroutine different from the one in which the dll was loaded.

I have a problem with the following code, which calls a routine named "SALTCHEM" located in a dll (saltchem.dll):

pp = loadlibrary("saltchem.dll"C)                       ! load the dll into memory 
qq = getprocaddress(pp, "SALTCHEM"C)          
!  set up a pointer to the routine "SALTCHEM" located in the dll 
call rtn_saltchem(...)                                         ! call the routine "SALTCHEM" 

This procedure works when all these statements are in the main program.
However, what I really want to do, is to call this routine "SALTCHEM" from another subroutine X,
i.e. not from the main program where I loaded the dll.
So, I'm setting up the pointers pp and qq in the main program, as above,
then I'm bringing them over to subroutine X which now contains the call to "SALTCHEM" (call rtn_saltchem(...)).
This seems to work when I bring over the pointers pp and qq from the main program to subroutine X
through a COMMON block, but it doesn't work when I bring them over through a module.
In the latter case, I get the following compiler error:

Error: This scalar name is invalid in this context. [RTN_SALTCHEM]

Why does it work with a COMMON block but not with a MODULE? Any suggestions?

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Looks to me as if the compiler doesn't know rtn_saltchem is a pointee. Is the POINTER declaration visible to routine X?


Retired 12/31/2016

Ok, I whipped up a small example and I can see that if you have just a POINTER statement in the module, then the compiler doesn't treat rtn_saltchem as a callable routine. This sort of makes sense to me - there's nothing in the context of the module to say that it's a routine. When you use a COMMON, you have the call and the pointer declaration in the same program unit, so the compiler figures it out.

Here's the solution - add an INTERFACE for RTN_SALTCHEM to the module. Here's a complete example that works:

module mymod
pointer (p,q)
subroutine q
end subroutine q
end interface
end module mymod
subroutine one
use mymod
external three
p = loc(three)
subroutine two
use mymod
call q
subroutine three
write (*,*) "I'm three!" 
program main
call one
call two
Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today