Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29284 Discussions

Works in CVF, but not Intel Fortran - POINTER, USE, INTERFACE operations with LoadLibrary and GetProcAddress for run-time loading of DLL

FortranFan
Honored Contributor III
548 Views

I'm in the process of migrating some legacy code in Compaq Visual Fortran(CVF) 6.6 to Intel Fortran XE 2011 on Windows. There is a Fortran main program that does a run-time load of a Fortran DLL due to some unspecifiable constraints. The main program then uses GetProcAddress to get the address of some subroutines and functions in the DLL and it uses (DEC/Compaq/Intel) integer POINTER to point to these addresses. There is a module file (MOD) available that provides the INTERFACE statements for the callable routines in the DLL. The main program makes use of this module. It then connects the addresses returned by GetProcAddress to the function names from the module via the POINTER statement. A sample code is shown below.

This works well in CVF, however Intel Fortran gives the following error:
"error #6401: The attributes of this name conflict with those made accessible by a USE statement." Intel Fortran gives an error with the use my_interface, ONLY : my_dll_sub statement whereas CVF allows it.

Any idea how to resolve this error in Intel Fortran? Is therea compiler option or setting that needs to be used. I'm new to Intel Fortran XE 2011 and my settings are whatever that got picked up when the project was converted by Intel integration in Visual Studio 2010.

Thanks much in advance,

Sample code:

! *** Interface Module my_interface.f90

module my_interface

interface

subroutine my_dll_sub(x)

implicit none

real(8) x

end subroutine my_dll_sub

end interface

end module my_interface


! *** my_dll.f90 in my_dll.dll

subroutine my_dll_sub(x)

!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'my_dll_sub' :: my_dll_sub

implicit none

real(8) x

' process x

x = 2*x+1

end subroutine my_dll_sub

! ***MAIN PROGRAM
program myprog

use ifport

use ifwin

use my_interface, ONLY : my_dll_sub ! **** THIS WORKS IN CVF 6.6, BUT NOT IN Intel Fortran

implicit none

integer(handle) lib_handle

! DEC/Compaq/Intel integer POINTER

integer(4) p

pointer (p,my_dll_sub)

real(8) y

lib_handle = LoadLibrary("my_dll.dll"C)

p = GetProcAddress("my_dll_sub"C)

y = 3

call my_dll_sub(y)

write(*,*) y

end program myprog

0 Kudos
3 Replies
Steven_L_Intel1
Employee
548 Views
We fixed a bug that CVF had, where it allowed you to change the characteristics of a symbol that was USE-associated. You turned my_dll_sub from an external procedure to a pointee. We fixed the bug in Intel Fortran.

Here's how to make this work in Intel Fortran, and rather than use the POINTER extension I show you how to do it with Fortran 2003 features. I omitted the actual DLL code. This could be simplified a bit if you wanted to give up the error checking.

[fortran]! my_interface.f90

module my_interface

abstract interface

subroutine my_dll_sub_int(x)

implicit none

real(8) x

end subroutine my_dll_sub_int

end interface

end module my_interface




! main program
program myprog

use ifport

use ifwin

use, intrinsic :: iso_c_binding

use my_interface, ONLY : my_dll_sub_int ! THIS WORKS IN CVF 6.6, BUT NOT IN IVF

implicit none

integer(handle) lib_handle

procedure(my_dll_sub_int), pointer :: my_dll_sub
integer(C_INTPTR_T) :: p

real(8) y

lib_handle = LoadLibrary("my_dll.dll"C)
if (lib_handle == 0) stop "DLL not loaded"

p = GetProcAddress(lib_handle, "my_dll_sub"C)

if (p == 0) stop "MY_DLL_SUB not found"

call C_F_PROCPOINTER(TRANSFER(p,C_NULL_FUNPTR), my_dll_sub)

call my_dll_sub(y)

write(*,*) y

end program myprog[/fortran]
Note that the interface has changed to an "abstract interface", since there is no external routine by that name to be linked in. It would work without the "abstract" too.
0 Kudos
FortranFan
Honored Contributor III
548 Views
Hello Steve,

Absolutely Brilliant! Thank you very much!

Your suggestionswork like a charm plus it is a lot more cleaner since they are allbased on all Fortran 2003 -I assume standard 2003 since the Intel Fortrandocumentation shows no color-coding on any of the features such as ABSTRACT INTERFACE, C_INTPTR_T, C_F_PROCPOINTER, etc.

By the way, what is the recommended file-naming convention for source files that use Fortran 2003 features? Should they have .f2003 or some such extension? Or is .f90 still preferred to designate any free-form source whether it be based on Fortran 90, 95, 2003, or 2008?

Regards,
0 Kudos
Steven_L_Intel1
Employee
548 Views
Those are all Fortran 2003 standard features.

Use .f90 for free-form source. It was a mistake, in hindsight, for compilers to use .f90 for that purpose as it was never intended to represent the standards revision level.
0 Kudos
Reply