Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

can build a DLL, but cannot run it on another pc

Brian_Murphy
Novo colaborador II
5.501 Visualizações

I have built a very simple DLL using Intel fortran.  I can successfully call a routine in it from an Excel visual basic macro on my own computer, but not on another computer.  I get a message about "file not found" and "error 53".

I think the right compiler options are what I'm looking for.  Can anyone tell me what I need to do?

So far I'm doing everything with 32 bit options, and Excel is a 32 bit version.  Once I get this working, I want to get it working for 64 bit Excel.

Thanks,

Brian

 

0 Kudos
20 Respostas
mecej4
Colaborador honorário III
5.466 Visualizações

One suggestion is to do this in two steps. In the first step, write a short driver (in Fortran, C, C#, etc.) to call the DLL with representative arguments, and get this to run on the target machine(s). This step will take care of having the correct Fortran runtime installed on the target machine.

After this succeeds, move on to the second step, in which you work out the details of calling the DLL from Excel/VBA.

It was not clear to me from your post as to which files were missing and where the error messages came from - Excel?

Steven_L_Intel1
Funcionário
5.466 Visualizações

What Excel is trying to tell you is that your DLL is linked to other DLLs - the Intel Fortran and Microsoft C++ run-time library - not present on the other PC. You could install the Intel and Microsoft redistributable packages on the other PC, but for a DLL that is being called from Excel, I suggest instead that you change the project property Fortran > Libraries > Use Runtime Library to "Multithreaded" instead of "Multithread DLL", then rebuild. You then will (probably) have no dependencies on other DLLs.

PeterTheRascal
Principiante
5.466 Visualizações

Some lessons I have learnt debugging Excel to  DLL code

1. While Steve Lionel has recently convinced me that  Dependency Walker utility is far from perfect, it may help you crack which DLLs,if any, are missing. (Steve has just replied on this!!)

2. For now, I recommend using full DLL file names in your VBA Declare statements as this removes any ambiguity. . This is important as, when launched, Excel's "current directory" (i.e. first in Window's search strategy) is not usually the launch directory (It can be made do by judicious VBA)

3. yes, I agree a Fortran DLL test program is also useful.

 

Brian_Murphy
Novo colaborador II
5.466 Visualizações

Thanks very much for the suggestions.  I changed Multithreaded DLL to Multithreaded and rebuilt everything.  The Debug and Release versions both run on my computer, but still will not on another.  The error message is the same "file not found".

I know about the path requirements for Excel to be able to load my DLL, and my VBA code has statements to set the path.  This was required to get it working on my computer.

Over the years I've used Compaq 6.1 to make many DLL's, and somehow I got those to work on any computer without having to deploy anything additional.  So I expect to be able to do this with Intel Fortran once I get things set right.

I've loaded both the Debug and Release versions in Dependency Walker 1.0 dated 1996. 

For the Release version, it says KERNAL32.DLL, KERNALBASE.DLL and about 20 various API-MS-WIN-CORE-xxxxx files.  

For the Debug version, it complains about "mismatched machine type", but then lists the same DLL's as the Release, in addition to libifcoremdd.DLL and msvcr11d.DLL

This is a very simple bit of fortran code that I'm compiling, just to get the methods worked out before moving on to the real deal.

Thanks,

Brian

Steven_L_Intel1
Funcionário
5.466 Visualizações

If you are seeing libifcoremdd and msvcr11d, then what happened is you changed the properties for one configuration but not all. Don't use a Debug configuration when taking code to another system, use Release. And when in the Release configuration, change the property. (Or select "All configurations" and "All platforms" on the property page.

The mismatched machine type is a longtime bug in Dependency Walker - I don't know why it is still there. Ignore it.

Brian_Murphy
Novo colaborador II
5.466 Visualizações

Visual Studio 2012 doesn't cooperate with me all the time.  I set "all platforms" and it won't apply my changes to all platforms.  So I went through and changed them for each, and made sure they got changed.

Anyhow, I am compiling both Release and Debug and testing both on my computer, and others (which are VM's on my computer; XP, Vista, Win7 and Win8).  At the moment I am testing with XP and Win7 in the VM's.

I have built this test case code with Compaq 6.1, and that DLL will run on both mine and the other computers.  I've run out of ideas.

My latest attempt with Intel Fortran says the Release version "depends" only on KERNEL32.DLL, but it still won't run on another computer.  The Release version built with Compaq 6.1 says it depends on KERNEL32.DLL  plus also MSVCRT.DLL, and this one will run on other computers.

Brian

IanH
Colaborador honorário III
5.466 Visualizações

If you are statically linking to the fortran runtime, then dependency walker should not be listing a fortran runtime DLL.  Make sure that the DLL you are examining is the DLL that you are building.

Similarly, within Excel you should ensure that the DLL that Excel is trying to load is the DLL that you think Excel should be trying to load.

(It is embarrassing how many times I have been tripped up by the above.)

Note the debug runtimes are not re-distributable (there's a redist.txt file in your compiler's program files tree that tells you what you can redistribute (here I find it in the directory for the mkl documentation - which is one of the less intuitive things I have encountered this morning, and that's after three cups of coffee)) - so the fact that you can't find them on the target machine means you are following the rules.

This is perhaps incidental - but your version of dependency walker is ancient.  See http://www.dependencywalker.com/ to pick up a later copy.  Note that there are x64 and x86 variants - I think you get the most accurate results when you run the variant that relates to the bitness of the executable that you are applying the tool to.  Or maybe it is the bitness of the operating system.  Or both.  I can't remember.  Dammit, where's that fourth cup...

(If you don't go down the path of static linking the runtime as suggested by Steve (which might be easiest in the short term - unless you are using OpenMP) - then don't despair - using dynamically linked runtime DLL's from within Excel is certainly possible.)

 


 

Brian_Murphy
Novo colaborador II
5.466 Visualizações

Thanks for the suggestions, Ian.

I have confirmed that the DLL is the correct one, and it is being loaded from the correct folder.

I don't know how to tell if linking is static or dynamic.  Can you tell me how?

I downloaded the latest Dependency Walker, and it reports the same information as the old one.  So no help there.  It says the dependencies for the Intel version are basically the same as the Compaq version, but it still will only run on my computer, and not the others.  Actually, the Compaq one has an additional dependency that the Intel one does not have (see earlier post). 

The problem must be something really simple, but I just can't find it.

If you want to see what I've got, download this www.xlrotor.com/temp/SimpleFortranExcelDLL.zip

I could not figure out how to upload a file to a forum posting.

Brian

Brian_Murphy
Novo colaborador II
5.466 Visualizações

467742

Here is the file.  Maybe.

Brian

 

IanH
Colaborador honorário III
5.466 Visualizações

As described upthread, you can inspect the project properties (Fortran > Runtime Libraries) to specify/see whether the runtime is being linked statically or dynamically.  In the project properties you can also inspect the command line for the build (Fortran > Command line) and examine the /libs:xxx command line option to see the implications of your runtime library selection.  After something is built you can use dependency walker to see which DLL's it uses (if you see intel runtime dll's - you are dynamically linking).  The project settings and DLL's in that zip file are all set to and reflect static linking.

Your problem is perhaps not related to the Fortran or C runtimes.  How are you invoking this thing from excel?  Can you also attach the spreadsheet?

(  Not pertinent to your problem, but not that you have set the runtime for the debug configuration to be the release runtime - with the debug configuration active, in the properties for the project Configuration Properties > Fortran > Runtime Libraries shows "multithreaded", normally you would want "Debug Multithreaded".

Perhaps similarly irrelevant, but there are unexpected significant differences between the debug configuration and the release configuration.  The release has /winapp (i.e. Fortran > Libraries - Use Command Windows Libraries is set to yes) and /4Yportlib (i.e. Use Portlib Library is set to yes), the debug configuration does not.  Those are not settings I would expect to differ from debug to release.)

Note that using tabs in Fortran source code will make you go blind.

Brian_Murphy
Novo colaborador II
5.466 Visualizações
The Excel workbook file that calls the DLL should be in both the Release and Debug folders. The workbook and the DLL that it calls need to be in the same folder. Upon opening the file, click the "Button 1" button to run the macro that calls the DLL. If it runs, the numbers on the sheet will change each time you click the button. If it doesn't run, some sort of visual basic error message should be displayed. To see the code in the VBA macro, press Alt-F11 on the keyboard. Or if you get an error message, click the Debug button in the error message box. This excel workbook works perfectly on all computers with the Compaq version of the DLL. With the Intel version of the DLL, it will only run on my computer. In the Compaq version that runs on all computers, the fortran statement that exports the routine is this: !MS$ ATTRIBUTES DLLEXPORT :: SIMPLEFORTRANEXCELDLL In the Intel Fortran version it is this: !DEC$ ATTRIBUTES DLLEXPORT :: SIMPLEFORTRANEXCELDLL !DEC$ ATTRIBUTES STDCALL,REFERENCE,ALIAS : "SIMPLEFORTRANEXCELDLL" :: SIMPLEFORTRANEXCELDLL Is there something wrong with these statements? The Visual Studio project settings that you mentioned not being the same in Release and Debug are because I was trying the shotgun approach to find something that would work. If you feed the Release version of the DLL to Dependency Walker, it should tell you that there are no dependencies other than KERNEL32.DLL. At least, that’s what I get. I desperately need to solve this problem to be able use Intel Fortran. Why the knock on using tabs in fortran source files. Is it something about Visual Studio? Brian
mecej4
Colaborador honorário III
5.466 Visualizações

I noticed in your example code, an include directive for IMSL, commented out. If your real code uses IMSL, and you pass a function or subroutine as an argument to an IMSL routine, here are some warnings. The IMSL 7.01 that is distributed for use with IFort expects that function/subroutine to have CDECL linkage, not STDCALL.  Therefore, you will have to mark those routines that are to be called from Excel STDCALL, leaving the rest CDECL. Using a compiler option to set the global linkage to STDCALL will not work.

Why the knock on using tabs in fortran source files. Is it something about Visual Studio?

The compiler and any editor that you use, including the VS editor, have separate notions as to how to interpret tab characters in source files. I have noticed a large number of support requests where tabs, which are invisible most of the time, were the culprits.

Brian_Murphy
Novo colaborador II
5.466 Visualizações

Thanks for the tip about IMSL.  I'm not using any IMSL routines that require passing those sorts of arguments, but it's good to know about that in case I do.

Do you think my current problem is a hidden dependency?  The DLL runs fine on my computer, but not any others.  Dependency Walker says only KERNEL32.DLL is needed.

When you want to build anything with Intel Fortran that won't depend on anything else, how do you do that?

Brian

 

Steven_L_Intel1
Funcionário
5.466 Visualizações

You already did it. Now figure out why Excel isn't loading the DLL you think it is.

Brian_Murphy
Novo colaborador II
5.466 Visualizações

I will go through everything again this weekend.  But I'm pretty sure this is a problem with my Intel Fortran project settings.

If you try to run the excel file in the Release folder of my zip file, I predict it will run for you because you have intel fortran installed.  If you take it to another computer (or VM) without Intel fortran, it won't run.  And Dependency Walker won't be any help in figuring out why.

Brian

 

IanH
Colaborador honorário III
5.466 Visualizações

Note that when I run depends on the debug\simplefortrandll.dll in that zip file, I don't see any exports from the DLL.  The DLL does not reflect the source code in the zip.  I do see exports from the release variant of the dll.  See the following screenshot - the panels on the right are blank.  This is 32 bit depends (matching the 32 bit dll) running on 64 bit windows.

depends-on-debug.png

The short list of immediate "windows system only" dependencies in the top left pane tells me that the dll has no dependencies on the fortran or Visual Studio runtimes.  The release variant of the DLL has similarly no runtime dependencies. 

If I recompile the debug configuration, then the DLL has an exported procedure, as expected.

Error messages about missing delay load DLL's can be ignored.

I can build a small test spreadsheet in Excel 2013 that loads the DLL and executes the subroutine.  When the DLL is loaded in Excel, if I use process explorer to inspect the DLL's loaded into the process, I see nothing that looks like an intel fortran runtime dll.  (Excel loads 1.2 billion dlls by default, so it is possible that I have missed one).  I do see references to the VS2010 C runtime dlls, but these are being picked up from a subdirectory of the excel installation - excel 2013 itself has probably been built by the VS2010 C++ compiler.

Unfortunately I don't have any windows machines that don't have ifort runtime not installed but do have excel installed to test

My test spreadsheet has two components - some mechanical stuff for the workbook as a whole that gives some flexibility to where the DLL I want can live, and then a test module page itself.  Those two components attached below.

Steven_L_Intel1
Funcionário
5.466 Visualizações

How about putting in the complete path to the DLL? I still think you're loading an old copy.

Brian_Murphy
Novo colaborador II
5.466 Visualizações

Good news.

It's working now for the most part.  I rebuilt everything and tested it in XP, Vista, Win7 and Win8 with various versions of Excel (2003, 2007, 2010 and 2013).  Calling the DLL is now working in all except XP.  Did I change or fix anything?  Not that I know of.

I then built a 64 bit version of the DLL and tested it with 64 bit excel, and even that is working.  Yahoo!

Although not a showstopper, I would like to figure out why it's not working with XP.  I tried putting in the full path name in the VBA Declare statement, but that didn't make any difference.  I vaguely recall reading somewhere about a glitch between the Visual Studio/Intel Fortran combo and XP.  Is there such a thing?  Maybe it was for installing Visual Studio/Intel Fortran in XP.

On my development system (Win7-64bit), I tried copying the msvcrt DLL files from the WOW folder to my XP machine and put these in the folder with my DLL and test spreadsheet.  That didn't make any difference.  I still get the dreaded "file not found" error.

When I run Depends.exe on the Release version DLL, on my Win7 development system, I don't get any messages in the bottom pane.  When I run the same Depends.exe on the XP system with the same DLL, there is the following error message in the bottom pane of the Depends window.

Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.

Can anyone tell me what that means?  Is it important?  Could there be something wrong with my XP test system.

Ian - thanks very much for taking such an in-depth look at my code.

Thanks,

Brian

 

Steven_L_Intel1
Funcionário
5.466 Visualizações

Ah, XP. You didn't mention that before. See here - in particular the part about installing VS2012 SP1.

You didn't say WHICH module had the unresolved import or what that was, but one of the issues with VS2012 was that it included MSVC library calls not supported on XP. VS2012 SP1 fixes that.

Brian_Murphy
Novo colaborador II
4.776 Visualizações

Sorry about that, Steve.  I intended to make it clear about the various OS's I was working with, but I guess I didn't do that well enough.  Also, I guess I was focusing a bit too much on XP, or else I would have realized sooner that the darn thing was working with Vista and the others.

I don't see anything in my "About Visual Studio" that indicates what service pack or update I have.  So in the next day or so I will try to get VS updated.  If I'm really lucky, this will cure another problem I have where the VS2012 debugger won't stop at breakpoints in VB.Net code when it's called from Excel VBA.  I don't have this problem on other computers with other versions of VS.

Cheers,

Brian

Responder