- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
We are in the process of migrating our codes from IFORT compiler to IFX compiler. We encountered error LNK2001: unresolved external symbol SETDLLEXTRAINFO and
error LNK2001: unresolved external symbol GETDLLEXTRAINFO for the interface of subroutines in the DLL. The interface declaration is as follows:
Interface
Subroutine getDLLExtraInfo( iMod , aString, iInfo, rInfo )
Character (Len=255) aString
Integer iMod, iInfo(10)
Double Precision rInfo(10)
!DEC$ ATTRIBUTES DLLExport, StdCall, reference :: getDLLExtraInfo
End Subroutine getDLLExtraInfo
Subroutine setDLLExtraInfo( iInfo, rInfo )
Integer :: iInfo(10)
Double Precision :: rInfo(10)
!DEC$ ATTRIBUTES DLLExport, StdCall, reference :: setDLLExtraInfo
End Subroutine setDLLExtraInfo
End Interface
We tried with both Intel oneAPI Compiler 2023.1.0 and 2024.1.0 as well. The latest version also didn't help much. Any help or suggestions will be greatly appreciated. Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks - I can reproduce the problem using IFX but not IFORT. The really curious thing is that the error message names Test_1.exp as the referencing file, and you don't have such a file. This appears to be an object file created by IFX for the purpose of naming DLLEXPORTed names, and it is failing to downcase the procedure names. This is a bug, or perhaps (see next paragraph), the bug is that IFX isn't just ignoring DLLEXPORT here as it should.
Your code has a bug as well, that being putting DLLEXPORT in the interface to the procedures. DLLEXPORT in an interface doesn't make any sense, and it's not correct for what you're doing here, since these routines are not being linked to from a DLL, but rather you're using GetProcAddress to find these routines in a DLL you've presumably loaded with LoadLibrary. Take out the DLLEXPORT in the directives.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll note that one of the effects of the STDCALL attribute is to downcase the external symbol name. Given that ifx is x64-only, the use of @n suffixes doesn't apply, but the default of pass-by-value does. That the errors relate to upcased symbol names suggests that either the interface was not seen or that ifx is not properly interpreting the STDCALL attribute. I tried a test case to see what happened and it worked as I expected.
If you could provide a complete test case, we'd be glad to look at it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Steve for your suggestions. I tried with lowercase symbol name with no success (tried with 2023.1.0 only though).
...
!DEC$ ATTRIBUTES DLLExport, StdCall, reference :: getdllextrainfo
...
!DEC$ ATTRIBUTES DLLExport, StdCall, reference :: setdllextrainfo
...
If I change the 'reference' to 'value', I get
Error error #6445: A dummy argument is required in this context. [GETDLLEXTRAINFO]
Error error #6445: A dummy argument is required in this context. [SETDLLEXTRAINFO]
If I provide the dummy arguments there, I get other errors.
I looked into the DLL routines (Fortran) and there also the STDCALL symbol names have a mixed case (as I have shown in my original post), but it doesn't throw any errors there. The DLL projects compile successfully. Not sure why, but the main kernel throws LNK2001 errors.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The subroutine which calls these routines is as shown below (I have removed some sensitive information).
Subroutine Get_Set_Extra( p_DLL, iSet )
use kernel32
! I removed some sensitive info from this routine
implicit None
integer (kind = int_ptr_kind()), intent(in):: p_DLL
integer, intent(in):: iSet
integer :: iInfo(10)
double precision :: rInfo(10)
Interface
Subroutine getDLLExtraInfo( iMod , aString, iInfo, rInfo )
Character (Len=255) aString
Integer iMod, iInfo(10)
Double Precision rInfo(10)
!DEC$ ATTRIBUTES DLLExport, StdCall, reference :: getdllextrainfo
End Subroutine getDLLExtraInfo
Subroutine setDLLExtraInfo( iInfo, rInfo )
Integer :: iInfo(10)
Double Precision :: rInfo(10)
!DEC$ ATTRIBUTES DLLExport, StdCall, reference :: setdllextrainfo
End Subroutine setDLLExtraInfo
End Interface
Integer (kind = int_ptr_kind()) p_Func1, p_Func2
Integer iErr, iMod
pointer (p_Func1,getDLLExtraInfo)
pointer (p_Func2,setDLLExtraInfo)
p_Func1=getprocaddress(p_DLL,"getdllextrainfo"C)
if ( p_Func1 /= 0 ) then
!... removed some code
Call getDLLExtraInfo(iMod , aString, iInfo, rInfo)
end if
p_Func2=getprocaddress(p_DLL,"setdllextrainfo"C)
if ( p_Func2 /= 0 ) then
!... removed some code
Call setDLLExtraInfo( iInfo, rInfo )
!... removed some code
end if
End Subroutine Get_Set_Extra
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you attach a ZIP file with just minimal sources that demonstrate the problem? Also give the commands you use to build. You can remove everything other than declarations and the calls.
Specifying a lowercase name after the :: in the directive has no effect, as Fortran is normally case-insensitive.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
Kindly find attached a very simple console example. I haven't changed any project settings. Just created a console project with all default settings. When I use the Intel Fortran Compiler Classic (IFORT), the program compiles fine. When I change it to Intel Fortran Compiler (IFX), it throws the exact same LNK2001 errors that I have reported in my original post. I can reproduce the error. I hope this will be helpful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks - I can reproduce the problem using IFX but not IFORT. The really curious thing is that the error message names Test_1.exp as the referencing file, and you don't have such a file. This appears to be an object file created by IFX for the purpose of naming DLLEXPORTed names, and it is failing to downcase the procedure names. This is a bug, or perhaps (see next paragraph), the bug is that IFX isn't just ignoring DLLEXPORT here as it should.
Your code has a bug as well, that being putting DLLEXPORT in the interface to the procedures. DLLEXPORT in an interface doesn't make any sense, and it's not correct for what you're doing here, since these routines are not being linked to from a DLL, but rather you're using GetProcAddress to find these routines in a DLL you've presumably loaded with LoadLibrary. Take out the DLLEXPORT in the directives.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Steve. Yes, the problem only occurs with IFX, not with IFORT. Test_1 is the project as well as the solution name. The main program lies in Test_1.f90 and that file is included as well (Zip includes everything in that folder - Test_STDCALL). Thank you for your testing and pointing out the bug. If I take out the DLLEXPORT in the directives, it does compile successfully. I'll check if there is any side effect in our testcases due to taking out DLLEXPORT in the directives.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know the project is named Test_1 - I was referring to Test_1.exp, a file that is created during the build, not part of your project.
For what it's worth, DLLIMPORT in an interface is a thing, but you don't need it either. DLLEXPORT is right out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have no idea about Test_1.exp file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As I said, the .exp file is created by the build process, not by you. In the case of DLLEXPORT appearing in an interface block, the compiler should simply ignore it as the only place DLLEXPORT should appear is in the source of the procedure being exported.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page