i am posting this having gone through a number of threads on this forum regarding this issue.
So I have a legacy GUI app that runs using a dll. My task is to improve on the app. So I got the source codes folder from the developer. In there amongst other things we have two dll source codes - one calling a sub from the other, and one source code for the gui. The legacy code was built in the 90s using Compiler: MS Developer Studio,Fortran Power Station 4.0. Now I am using Visual studio with Intel(R) Visual Fortran Intel(R) 64 Compiler.
My Challenges are:
1. Can I use the above compiler for the same code to get the same result
2. Can I merge the 2 dlls into 1 by copying the called dll codes into the calling dll code
3. I keep getting a number of errors when i tried to build the gui source code in Qwin viz:
So I played around a little bit turning off some optimization level and removing some lines of code eventually i arrived at this 2:
I have been on this for a month and would appreciate anyhelp.
You have to admit there are some large pieces of info missing here.
First - you should be able to build a Powerstation Fortran program with Intel Fortran, with a few possible glitches. MSPS had a few extensions that may not have been replicated in Intel Fortran, but for the most part, the extensions (and of course all standard Fortran features) are supported.
Second - I think the problems you were having compiling your QuickWin program was because the program was actually fixed-form, but had a free-form name (in other words, it was called FOO.F90 which implies free-form). I say this because only fixed-form allows "C" comment delimiter.
Are the DLL source files in Fortran or C?
What do the declarations for DLLVER and METHAN look like in the file that defines them? What do the calls to these routines, or references to these entities, look like in the source file that created "nm.obj"?
Thanks for the response!.
I have tried changing the extensions to .f,.f90,.for, but none is fixing the problem
The dll sources are in Fortran
The subroutine names were declared in a common block file and included in the dll.
The calls to the subroutines were made using an Interface block.
How do you suppose I changed the file from fixed form to free form. Or what compiler can I use to compile the code in fixed form. Thanks.
The easy question first; the same compiler can compile either fixed or free. That affects compile-time messages, but does NOT affect the link-time issue that you are having.
RE: 'The subroutine names were declared in a common block file and included in the dll.'
I'm sorry, I don't understand what this means. Yes, let me echo what Andrew suggested, and please show some source code. At the very least, I would like to see the declarations and the references for DLLVER and METHAN .
Yes, it is missing the ansi.cmn file,which is why I suspended compiling the dll for now. My goal is to build the gui sourecode into an exe that I can use with the available mzdll.dll.
I am using Visual studio 2005>> QWIN>> to build the GUI.
ah, OK ...
You have some interesting problems to overcome.
I do NOT believe that you can use a dll created with Microsoft Powerstation with ifort; there are many runtime differences between the two compilers.
It would be more productive to be able to build your application with a supported compiler. You only have the 2005 compiler available? Nothing any newer?
That said, I've been playing with this a bit. I can't find any routines in your code for ZEIT or for ISTRNG. The source files you submitted do not have routines to support these names. Looking at the code, I might guess that "ISTRNG" is equivalent to the standard intrinsic INDEX.
And again, as a guess, I'd say that ZEIT gets the date and time, and can probably be replaced with the standard DATE_AND_TIME if we supported that in the 2005 version of the compiler.
Because some of the symbol names used conflicted with the ones from MSFLIB, I changed all USE MSFLIB to this:
USE MSFLIB, msdate=>date, mslstat=>lstat, mstime=>time
What that does is tell the compiler to rename the variable "date" from msflib to msdate, the variable "lstat" to "mslstat", etc. That way the names do not conflict with date, lstat and time that are all defined in your common blocks.
So, what I think you should do is change the calls to ZEIT and ISTRNG to something supported by the 2005 compiler (the online compiler documentation is included in the 2005 package).
Then, build your dll using one or both of the source files; from the command line it would be something like:
ifort /dll mzdll.for mzdll1.for
Finally, now you should have mzdll.lib and mzdll.dll. You would build your final application as:
ifort mn.for /libs:qwin mzdll.lib
I think this will work. Let us know either way, OK?
Thanks for sacrificing your time to do this!
I am using Visual studio 2005 but my compiler is 'Intel(R) Visaul Fortran Intel(R) 64 compiler for applications running on Intel(R)64. Copyright (C) 1985-2009 Intel Corporation'
I do not think this implies 2005 compiler.
I introduced the above comment but when i try to compile it gave me this:
It is possible that Microsoft Powerstation will not run on a newer computer, and of course, I would rather get you working with Intel Fortran :)
This problem is very easy; your current-working-directory is one of Windows' system directories, and no, you do not have permission to create object files there.
Please move your files, and your current-working-directory, to a user directory somewhere else, and try again.
Finally, thank you for showing the version; I see that you are using V11 of Intel Fortran. That is a rather old version, but should allow you to do what you need.
Thanks for your help Lori. I used a simplified version of the code and followed the procedure you suggested , and I was able to compile the code. I would keep it open till i have all the information to compile the original code . Should I run into any issues again I would let you guys know.
Once again!. Thanks and I appreciate your help.
So I was able to compile the dll but when i try to call it i got this error message:
'The pocedure entry point _CETANE@16 could not be located in the dynamic link library"
What could be causing this?
The @16 suffix on the name tells me that the caller is expecting that CETANE uses the STDCALL calling mechanism. This is not the default in Intel Fortran. My recommended solution is to change the declaration of CETANE in the calling app to not use STDCALL. A simpler solution is to set the project property Fortran > External Procedures > Calling Convention to CVF. This will mimic what PowerStation did in this regard.
Thanks Gib for your response. Thanks Doctor Fortran. It's so nice to have you contribute on this thread.
So I tried all the suggestions raised.
Firstly, when i used: project property Fortran > External Procedures > Calling Convention to CVF. It gave me a new error when building my dll.
'UNRESOLVED EXTERNAL SYMBOL _GETENV@16 REFRENCED IN FUNCTION CETANE'
Secondly, the calling app does not use STDCALL.
Looking forward to more suggestions. By the way, I am trying to call the dll from excel.
In the routine that calls GETENV, just after the SUBROUTINE or FUNCTION, add:
1) Make sure you built a Release configuration and not Debug
2) The target system needs to have the Intel compiler redistributables installed, and maybe the Microsoft C++ redistributables for the version of Visual Studio you used.
If your DLL is not called from a C++ or Fortran program, you can simplify things by setting the project property Fortran > Libraries > Use Runtime Library to "Multithreaded" and not "Multithread DLL".
Thanks Steve. Your suggestion was on point for the 32bit. However, I couldn't get it to work for the 64bit version, it keeps giving me the error
"File not found"
Any help on this?