I am trying to modify a dll file that is used within a commercial software called WAMIT. The instruction manual for WAMIT states:
"WAMIT Version 7 is compiled with Intel Visual Fortran (Version 12.1). The previous Version 6.4PC was compiled with Intel Visual Fortran (Version 10.1) and earlier versions were compiled with Compaq Visual Fortran. Any of these Fortran compilers can be used to compile modiﬁed versions of the ﬁles geomxact.dll and newmodes.dll for use with a single processor (NCPU=1), using the following procedure:
• Open a new project ‘geomxact’ as a Fortran Dynamic Link Library
• Add geomxact.f to the project
• Build a release version of geomxact.dll
• Copy the new version of geomxact.dll to the working directory for WAMIT ....
...It may be possible to use other FORTRAN compilers to build the DLL ﬁles, but certain conventions in calling subroutines must be consistent with those of Intel Visual Fortran."
I have not been able to find any of these 3 old compilers, so have instead tried to rebuild the dll from the fortran file using Intel Visual Fortran Compiler 18.0 (from Intel® Parallel Studio XE Cluster Edition for Windows* 2018) together with Microsoft Visual Studio Enterprise 2015 (currently on a 30 day trial period). I am running on a 64 bit computer with Windows 10.
I have followed the above instructions from the WAMIT manual, however there is something different about the dll that is built, as WAMIT is unable to see the file, giving the error "The system cannot find the file specified".
I have asked the WAMIT developers, and they have told me that they do not understand Visual Basic so I should contact you, as they apparently did the last time that they changed compilers.
Please can you help me to troubleshoot this? Perhaps there are some options that I can add to the fortran project which will make the dll the same as when compiled by Intel Visual Fortran 12.1?
Many thanks in advance,
Much depends on which version of WAMIT is under use. Which version are you using? From the WAMIT documentation, it appears that versions 7.x of WAMIT are 64-bit, so what was written regarding 32-bit targets and STDCALL does not apply if you are using versions 7.x of WAMIT.
You really need to settle the 32-or-64-bit question first. Dumpbin /headers is one way to do so. For more ways, please see https://www.raymond.cc/blog/determine-application-compiled-32-64-bit/ .
If you want useful advice about the error messages that you see, you must be willing to share those error messages here. Those messages may mean little to you, but it may happen that the error message will tell someone else exactly what went wrong.
It sound to me like "The system cannot find the file specified". error message is a WAMIT message not a system message? what the root cause is is thus a bit of guesswork. Either:
a) WAMIT is failing to find your actually DLL file. on the LoadLibrary command
b) WAMIt is failing to GetprocAddress for one or more a functions in the DLL
The first is down the file name and search rules. For the second I suggest doing a DUMPBIN on an original dll that worked and on a new one to see the ordinals/names that are defined in each case. That should give clues as to what the problem is.
This sounds like WAMIT is an executable that (among other things), it appears that WAMIT calls a DLL that you build using Intel Visual Fortran, the DLL named geomact.dll. The file you build (geomact.dll) must reside in a path specified in the PATH environment variable .or. in the current directory .or. in the same directory as WAMIT.
*** Note, "The system cannot find the file specified" may also refer to some other file. Usually the xxx.dll file name is listed in the error dialog, but this may not be the case for WAMIT, this could also mean WAMIT.exe itself is not found due to clicking on a ShortCut that specifies an incorrect location for WAMIT (e.g. you copied the shortcut from a different system and installed WAMIT somewhere other than where it was located in your other system).
Thanks for getting back to me. You are correct that WAMIT is an executable that calls geomxact.dll. I would like to edit the fortran code from which the dll is created, but first I need to check that I am able to build a dll that will work. To do this, I have taken WAMITs original fortran code (without any modifications), compiled it and replaced the original dll in the original dll location. This means that the only thing changing from the case that works, to the case with the error message is that dll has been switched with one compiled myself. It has the same name, the same location and the same fortran file from which it is created, and nothing else is changed externally to this. This leads me to think that I am unable to build the dll in a manner that WAMIT is able to read.
The WAMIT manual is very specific about using one of the three compilers that they specify, but I would guess that there is a way to use a newer compiler provided some options are selected. Do you have any idea what difference it would make to use Intel Visual Fortran 12.1 instead of 18.0?
The "old versions" available officially from Intel aren't old enough. Do you know if I get any of the 3 specific versions that I need?
12.1 is available, but I am skeptical that will help you. It probably also doesn't support your current environment.
The error message indicates that the dll is not found.
Leaving everything the same, copy the old .dll to the same location (replacing the new dll, not creating "geomxact.dll (Copy1)").
Then issue the run of WAMIT exactly as you did when error occurred.
If you get the same error, then the path to the DLL is not available to WAMIT (or WAMIT itself is not available).
If the program runs, then this may be the 32-bit verses 64-bit issue (Repeat Offender)
The DLL may have been found, but the entry point may have not been located and WAMIT is displaying an incorrect error message. What can cause this to be an issue is the Fortran generated entry point name might not be in the same format as expected by WAMIT. WAMIT may be expecting "C" formatted names in lowercase with (or without) underscore (_), and the Fortran maybe defaulting to using uppercase letters. As Andrew suggests you can use DUMPBIN on both files to see if the entry point names differ (assuming issue not 32-bit verses 64-bit).
ADDED: Your program WAMIT may require a specific "Short Filename". This may be the case that the old/working file has GEOMXACT.DLL, and the new file has GEOMXA~1.DLL (or something similar). If the command to load the dll is using the Short Filename and it differs, then this can be a source of the problem.
The documentation of WAMIT indicates that the DLL should not only be a 32-bit DLL, but should also have been built to use the STDCALL convention for the exported routines. I surmise that this is so because of the numerous references to Compaq Visual Fortran in the manual.
Please check your installed WAMIT to confirm this suspicion and, if it turns out to be true, specify 32-bit/Release as the target and specify the compiler option /iface:cvf . What is more, building the DLL with the wrong calling convention and seeing it fail may have caused the problem to be misdiagnosed as attributable to the use of an "incompatible" newer compiler version.
Thanks for your advice. I think that it is really good advice, but I perhaps am implementing it wrong. So:
1) "Please check your installed WAMIT to confirm this suspicion": How do I do this?
2) " specify 32-bit/Release as the target": I have tried to do this, but am not certain I did it correctly. How exactly do I specify a 32-bit/Release as the target? Currently I have selected "x86" solution platform, which I understood to be 32-bit release. Is that correct? In the release solution properties it states in the upper platform box "x86" and the lower platform column "win32". These are both drop down lists, with no altenatives offered.
3) "specify the compiler option /iface:cvf": To do this, I right-clicked on the fortran file within the project, clicked properties, and in the left-hand pane of the properties window, clicked "Fortran" then "Command Line". In "Command Line", there is a box named "additional options" into which I typed "/iface:cvf".
So, have I followed your instructions correctly?
The build log states:
Build started: Project: newmodes, Configuration: Release|Win32
Compiling manifest to resources...
newmodes - 0 error(s), 0 warning(s)
(Note that the file I am trying to create is newmode.dll, which the WAMIT manual states should be compiled in the same way as geomxact.dll).
Just to be clear, there are several files created in the release folder, but I only take the newmodes.dll file and copy it into the correct location, ignoring the other files. The dll still builds with no errors, but cannot be read by WAMIT for some reason.
Sarah, doing a dumpbin on the OLD working dll will give answers to many questions. If it is stdcall 32 bit for example the name will be "decorated" e.g. name become _name@nn (where nn is byes passed)..... At the moment we are making guesses and posting possible solution to guesses....
I have just been trying to do this based on your earlier comment. It definitely seems like good advice, but again I am not sure how to implement it. I am guessing that you would like me to add some options to dumpin? If I just do DUMPIN filename, then I get the following:
"Dump of file C:\wamitv7\newmodes.dll
File Type: DLL
Following on from my last comment, if I do the same DUMPBIN on the new dll I get the following instead:
The default dumpbin (no options) shows symbols. That dll dumbin contains no exported symbols, your code is probably missing some DLLEXPORT commands. What does the dumpbin of the old and previously working dll look like?
I have just tried using DUMPBIN/EXPORT filename on each file, and I can see a difference.
Section contains the following exports for newmodes.dll
5A17E996 time date stamp Fri Nov 24 10:42:46 2017
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 00001020 NEWMODES
2 1 00001020 _NEWMODES@80
I don't really understand what this means though? Why are there 2 names for the new dll?
As an extra point, a couple of people have question the error message I get. I just want to confirm that this is an error from within WAMIT about not being able to see the file. WAMIT error messages are often very unclear, so I have no extra detail on this.