- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am experiencing a problem whilst compiling myexecutable application using ifort 12.0 in Microsoft Visual Studio 2008. I have a preprocessor line in the source code to define the interface to an externalsubroutine that is available through alinked DLL (windows) or shared object (linux). This interface depends on the platform and looks like this:
INTERFACE
SUBROUTINE initialise()
#if _WIN32
!dec$ ATTRIBUTES ALIAS: '_DLL_mp_INITIALISE' :: initialise
#else
!dec$ ATTRIBUTES ALIAS: 'dll_mp_initialise_' :: initialise
#endif
END SUBROUTINE
END INTERFACE
This all goes well on linux when invoking: ifort -fpp -p
When adding /fpp /P in Visual studio I get the following error message:
error LNK2019: unresolved external symbol _INITIALISE referenced in function _MAIN__
A closer look at the intermediate output file (*.i) shows that the fpp does the right job but puts the output (# line number)after the preprocessor commandas well,which results in the !dec$ ATTRIBUTES command not being properly compiled. This although the /P flag is given..It appears to me that the fpp output (# line number) generally is not a problem, but in the INTERFACE statement it is. I have not been able to resolve this issue and hope anybody can help.
Kind regards,
Koen
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The interface is being provided as shown in the original post. When I comment the preprocessor part of the interface for linuxthe interface looks like this:
INTERFACE
SUBROUTINE initialise()
!dec$ ATTRIBUTES ALIAS: '_DLL_mp_INITIALISE' :: initialise
END SUBROUTINE
END INTERFACE
When I compilethis on windows with VS and donot use the preprocessorit works fine this way..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suspect the object file that is actually being linked in is an old one.
By the alias name it looks like you are trying to pretend that something that was originally compiled as a module procedure should now be treated as an external procedure? Why?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/fortran/win/index.htm#bldaps_for/common/bldaps_use_fpp.htm
But apparantly this option is not available through MVS?
Anyway the LNK2019 error also occurs if I just use /fpp and I do get an object file.
The alias name is to recognise the "initialise" subroutine that is present in a DLL module indeed. Hence I have a console project in MVS that is callling this subroutine which is located in the DLL module. The interface statement is to link this external routine. However this alias statement is different for a linux platform. See also the posted code above. This is why I am using the fpp to get the right alias statement for the right platform automatically. But since the fpp call adds an output line with a hash key # followed by the original line number, the linking process is corrupted somehow. I am sorry if I am confusing you too much here, but I hope somebody can help me out...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suggest you follow IanH's suggestion about USE-ing a module to sort things out. However, if you want to continue along with using FPP try:
#if _WIN32
INTERFACE
SUBROUTINE initialise()
!dec$ ATTRIBUTES ALIAS: '_DLL_mp_INITIALISE' :: initialise
END SUBROUTINE
END INTERFACE
#else
INTERFACE
SUBROUTINE initialise()
!dec$ ATTRIBUTES ALIAS: 'dll_mp_initialise_' :: initialise
END SUBROUTINE
END INTERFACE
#endif
If that fails, then use the FPP option to omit the line numbers from the file that has the above code.
Note, if this is a FORTRAN include file this would require your fortran code to omit the FPP line numbers, which may not be what you want. However to fix this, create a FORTRAN souce file containing your interfaces as a module file (like IanH's suggestion) which is compiled without the FPP line numbers, and then use USE thisModuleNameHere in your FORTRAN programs compiled without FPP.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Would you please attach a ZIP with your source file and other information that leads you to believe that the preprocessor is not doing the right thing? We have many customers using this and have not seen a similar issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
First of all thank you very much for your help on this matter. I found that the workaround as proposed by Jim was effective, but not very elegant with the bulky text. Linking through a USE statement is not an option I think since I need the shared object/DLL and the executable to remain separate at all times. Anyways I found out thatan ALIASstatementin the module would get rid of all my problems and does not necessitate me to use fpp anymore:
Subroutine initialise()
!dec$ ATTRIBUTES ALIAS: 'initialise' :: initialise
If I place this statement in the module where it is defined, this external routine always has the same name, independent of platform type. Hence if I put this statement also in the main program it will always recognise it. Problem solved!
For Steve's sake I have assembled the source files to recreate the problem. The only problem is that I have not succeeded in attaching the files here (although there is an Add Files button). An alternative suggestion to upload the files is welcome.
Once again many thanks for all your help!
Koen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you want a module procedure to have a particular linker name (and calling convention) then consider using a BIND(C, NAME='xxx') suffix on the subroutine or function statement for the module procedure and inside the relevant interface block. That's a lot more portable than the compiler directive.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have uploaded two VS projects (CONSOLE and DLL) that recreate the problem. Note that the lib file which is created by the module must be included manually in the console project.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is another suggestion:
#if _WIN32
#define USE_initialize'_DLL_mp_INITIALISE'
#else
#define USE_initialize 'dll_mp_initialise_'
#endif
INTERFACE
SUBROUTINE initialise()
!dec$ ATTRIBUTES ALIAS: USE_initialize :: initialise
END SUBROUTINE
END INTERFACE
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Suggestion 1: use the !DEC IF DEFINED(_WIN32) syntax rather than the # syntax.
Suggestion 2: Don't use directives at all: USE the module that declares INITIALISE and the correct name will then be automatically used. This would be my preference by far.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page