- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
I have a Fortran console application which is trying to import a routine from a Fortran dll. I'm getting the following error message when linking.
error LNK2019: unresolved external symbol __imp__USELOG referenced in function _MAIN__
The interface for the routine is:
INTERFACE
SUBROUTINE USELOG(logname, progname, version)
!DEC$ ATTRIBUTES, ALIAS:'USELOG' :: USELOG
!DEC$ ATTRIBUTES DLLIMPORT :: USELOG
CHARACTER(LEN=26) :: logname
CHARACTER(LEN=26) :: progname
CHARACTER(LEN= 5) :: version
!DEC$ ATTRIBUTES REFERENCE :: logname, progname, version
END SUBROUTINE USELOG
END INTERFACE
The routine USELOG uses the following code for exporting:
!DEC$ ATTRIBUTES DLLEXPORT :: USELOG
!DEC$ ATTRIBUTES ALIAS:'USELOG' :: USELOG
!DEC$ ATTRIBUTES REFERENCE :: logname_, progname_, version_
When I view the dll using dependency walker the routine is shown as USELOG without any decoration.
Could someone please tell me how to import this correctly.
Regards, Mike
- Balises:
- Intel® Fortran Compiler
Lien copié
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You need to link against the .lib generated when the DLL was built. If you tried linking to the DLL directly, that was ignored.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
I did link against the import lib. I have it listed in the Linker/Advanced/Import Lib.
I also added the import lib to the project.
Mike
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Ah - I've seen that error before. That's not the right place to add that. You want it under Additional Dependencies. What you did was tell the linker to name the import library it creates, if it created one, which it won't for an executable project. Treat the import library the same as a static library.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You are correct Steve. I think I moved the import lib address from the Additional Dependencies in an attempt to fix the original problem which is an unresolved external.
I am trying to use the routine USELOG from the dll. If I use an interface block in the calling program, I get this error:
error LNK2019: unresolved external symbol __imp__USELOG referenced in function _MAIN__ Besthb.obj
If I do not use an interface block, I get the following error:
error LNK2019: unresolved external symbol _USELOG referenced in function _MAIN__
Both errors say that the linker is looking for the routine USELOG with a prefix to the routine name.
Dependency Walker does not show any prefix when looking at the dll.
Mike
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
I decided to try a different approach. I created a static library to replace the dll. I added that as the additional dependency instead of the dll import library. I eliminated the Interface block. However, I still get the error:
error LNK2019: unresolved external symbol _USELOG referenced in function _MAIN__
The USELOG routine does show up as _USELOG in a Dumpbin listing of the static library.
Mike
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
I solved the underlying problem.
In the UseLog routine being exported from the dll, the DECORATE command was missing.
The codes should have read:
!DEC$ ATTRIBUTES DLLEXPORT :: USELOG
!DEC$ ATTRIBUTES DECORATE, ALIAS:'USELOG' :: USELOG
!DEC$ ATTRIBUTES REFERENCE :: logname_, progname_, version_
Question: Is it possible to tell the calling routine not to expect decoration?
Regards, Mike
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You could remove the ALIAS,DECORATE directive entirely in both the called routine and the caller. since all you're doing is restating the default.
When you use DLLIMPORT, the __imp__prefix is added. This is resolved by the import library and tells the linker to optimize the call (removes a few extra instructions. You don't see the prefix when examining the library or DLL. DLLIMPORT is optional when calling procedures, but is required if you are referencing variables or COMMON blocks in DLLs.
I will also comment that a nice way to handle this sort of thing is to put your DLL routine in a module, with DLLEXPORT. Then when the called program USEs the module, it will automatically get the interface AND do a DLLIMPORT. DO make sure that the executable links to the DLL run-time libraries.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
I use modules in VB, but haven't used them in Fortran.
Are you suggesting placing the entire routine in a module like the sample code below, or only a interface block?
MODULE MOD_TEST
SUBROUTINE UseLog(logname, progname, version)
!DEC$ ATTRIBUTES DLLEXPORT :: USELOG
!DEC$ ATTRIBUTES REFERENCE :: logname, progname, version
IMPLICIT NONE
INTERFACE
SUBROUTINE USE_LOG(logname, progname, version);
!DEC$ ATTRIBUTES DLLIMPORT :: USE_LOG
!DEC$ ATTRIBUTES DECORATE, ALIAS:'use_log' :: USE_LOG
CHARACTER(LEN=26) :: logname
CHARACTER(LEN=26) :: progname
CHARACTER(LEN=5) :: version
!DEC$ ATTRIBUTES REFERENCE :: logname, progname, version
END SUBROUTINE USE_LOG
END INTERFACE
! Type call list variables
CHARACTER(LEN=26), INTENT(IN) :: logname
CHARACTER(LEN=26), INTENT(IN) :: progname
CHARACTER(LEN=5), INTENT(IN) :: version
CALL Use_Log(logname, progname, version)
RETURN
END SUBROUTINE UseLog
END MODULE_TEST
Mike
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You would take out the INTERFACE - a routine in a module provides its own interface. See Doctor Fortran Gets Explicit - Again! for more information. Then add a USE MOD_TEST to the main program where you want the subroutine to be visible. You'll need to make the .mod file created when the module was compiled visible to the "Includes" path when building the executable. If you simply make the DLL project a dependent of the executable project, everything will be done automatically.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
In the sample code, the INTERFACE is actually for the routine USE_LOG which is a C routine in another dll. The Fortran routine USELOG is calling USE_LOG.
Mike
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Ah, I see. Yes, you need an interface for the C routine.

- S'abonner au fil RSS
- Marquer le sujet comme nouveau
- Marquer le sujet comme lu
- Placer ce Sujet en tête de liste pour l'utilisateur actuel
- Marquer
- S'abonner
- Page imprimable