Dll can’t be recognized unless in system directories when called from VBA.

Dll can’t be recognized unless in system directories when called from VBA.

Hi All,

I built a 32-bit DLL with Visual Fortran V11.1.067  within Visual Studio 2008 on my computer. The program is supposed to work like this:

EXCEL VBA (32-bit) calls “C:\Test\AA.dll” via the absolute path. Then “AA.dll” calls 3 others (libmmd.dll, msvcr90.dll, svml_dispmd.dll), which are all located in the same path “C:\Test\”. (The 3 dlls are actually Fortran’s inherent dlls, copied from the folder “…\lib\ia32”). It works fine on my computer. But on other computers, VBA always reports the “Run-time error 53:  C:\Test\AA.dll not found”.

To solve this problem, I monitored the program using the software “Process Monitor” and found that on other computers, actually AA.dll was found by VBA. But when AA.dll called any of the 3 dlls (libmmd.dll, msvcr90.dll, svml_dispmd.dll), the 3 dlls were scanned (or queried) from the path “C:\Test\”, but the result was unexpectedly “NAME NOT FOUND” shown in Process Monitor. Then VBA continued to search “C:\Windows\” and “C:\Windows\System32\” for the 3 dlls. If they were not there, the result was again “NAME NOT FOUND”. Finally, VBA showed the Run-time error.  Based on this finding, I copied the 3 dlls into “C:\Windows\”, then the dlls were found there, and the problem was solved.

But some of my users don’t want me to put the 3 dlls into their system folders, they want me to use the Desktop only. So the “Run-time error 53” comes to me again. So my question is “How can I make my AA.dll recognize the 3 dlls from any path, not limited to the system directories mentioned above?” Thanks very much.

Kindest Regards,

Jackie

16 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hello Jackie,

The standard way to do this for users who do not have Intel Fortran installed on their machines is have them install our redistributable library package.  That will install all the Intel Fortran libraries in a standard location and update the necessary environment variables such that anything needed at runtime will be found by the application.  This will avoid cluttering up C:\Windows or other system directories with DLLs that don't belong there.

For the 32-bit 11.1 compiler, the redistributable package is available in the Intel Registration Center, the package name is 'w_cprof_p_11.1.072_redist_ia32.exe.

Patrick

Thanks Patrick,

Thanks for your reply. I checked with my user about running the “w_cprof_p_11.1.072_redist_ia32.exe” on his computer. Unfortunately, files like .exe are not allowed to run on the computer due to the security regulations of their company. So I can only use the desktop, not even the system directories in his case.

So is there any other way to solve this problem? Can I do this by setting the environment variables to make the 3 dlls recognizable by VBA?

Thanks,

Jackie

Jackie,

If you build your DLL using the Multithreaded Runtime Library (/libs:static /threads) then the runtime libraries are built into your DLL, and no additional redistributables are required.

Then your DLL only needs to be somewhere on the PATH.  VBA can then call the DLL without having the explicit install location.

Just be aware, that if your end users have a 64-bit version of Office, then they cannot use the 32-bit DLL's.  Excel in this case will report that the DLL is not found, even if it is on the path.  The correct message should be that it is unable to load the DLL.

Regards,

David

Thanks David,

 

I just checked the library I am using. I can see from:

Project>Properties>Fortran>Libraries>Runtime Library, there are four options available (please see the attached figure):

1. Multithreaded

2. Multithread DLL (/libs:dll /threads)

3. Debug Multithreaded (/libs:static /threads /dbglibs)

4. Debug Multithread DLL (/libs:dll /threads /dbglibs)

The one I am using is No.2 “Multithread DLL (/libs:dll /threads)”.

In using this library, I have to use the 3 Fortran inherent DLLs (libmmd.dll, msvcr90.dll, svml_dispmd.dll). Because when I check my AA.dll with Walkers Dependency, my AA.dll is referencing to the 3 DLLs.

But I can’t find the (/libs:static /threads) option in my Fortran.

I am using the Release mode. And the EXCEL on my computer and my users computer are all 32-bit.

You mentioned “Then your DLL only needs to be somewhere on the PATH”, do you mean the PATH environment variable? I know little about the environment variable.

Thanks very much,

Jackie

Attachments: 

AttachmentSize
Downloadimage/jpeg My Fortran Settings.jpg102.94 KB

Jackie,

If you change the option to Multithreaded, then the runtime libraries get included inside the DLL.

Your choice whether you want the DLL to be in a fixed location, and the explicit folder name be included in the Declare statement in VBA, or you leave the path out of the Declare statement (Declare MyFunc Lib "MyDLL.dll"), and then add the fully specified folder name to the environment variable PATH.  If you are setting up an installer (this is how I do it), the installer automatically adds this.  Otherwise you may need to get the end user to do it.  In win7, it is found by searching for Environment in all programs, and in a locked down system, the path should be able to be added to the Users PATH (not the System part, which will be locked).

Regards,

David

Hi David,

Many Thanks! Using only one DLL is exactly what I want. I will follow your suggestions. I will first try the simpler way to use DLL in the Declare statement.

Thanks again,

Jackie

Jackie,

Just another tip, in case your customers are using different versions of Excel.

I found I had to add declares like this to accommodate Excel 2010:

#If VBA7 Then
    Private Declare PtrSafe Sub WaterDensity_F Lib "AWAProps.dll" _
        (TempC As Double, Value As Double, ByVal Units As String)
#Else
    Private Declare Sub WaterDensity_F Lib "AWAProps.dll" _
        (TempC As Double, Value As Double, ByVal Units As String)
#End If
 

Depending on which version of Excel you are testing on (we are still using 2007), the first declare will flag an error on the PtrSafe keyword when you enter this into your VBA code.  In Excel 2007 though, this line does not get executed.

David

Hi David,

Thanks for your useful advices.

I tried the Runtime Library “Multithreaded” and found that it did work on both mine and user’s computers. In this way only one DLL is needed. That’s more convenient in deed.

But one difference I found is that the DLL generated using “Multithreaded” will need more memory to load in VBA, although the size of the DLL file is the same as the one generated via “Multithread DLL (/libs:dll /threads)” method.

For example, using “Multithread DLL (/libs:dll /threads)” I can use 1 million grids in my calculation (I am doing CFD modelling). But using the “Multithreaded”, I need to reduce the grid number to 0.75 million, otherwise the “Runtime Error 7 – Out of memory” will be reported by VBA.

Do you know how to avoid using more memory when using the DLL generated from the “Multithreaded” method? Do I need to change other settings in Fortran?

Thanks very much,

Jackie

Sorry, I'll let the experts answer that one.

I'm guessing that with the runtime libraries included, you are loading all of the runtime libraries.  With the DLL version, then only the required libraries get loaded.  You might be able to add just the three libraries you need to your project (as in your original post), and then build the DLL. But I'll someone else with more experience on that advise you.

David

Are your grids being stored in static variables, or are you allocating space for variables using ALLOCATE?

I would have expected the total code loaded into memory for the statically linked variant to be less than that of the DLL variety.

Hi David and IanH,

 

This is a magic forum because I meet you two experts again here. I remember last year I asked one question, and you answered me. Thanks.

Ok, I think my variables are stored in static variables, because I am not using ALLOCATE. The way I define the arrays is as follows:

integer,parameter::N=2000

real*8,save::Temperature(1:N)

real*8,save::Velocity(1:N)

Could this be the result of my Fortran settings?

 

Thanks,

Jackie

This is a bit of a guess, but perhaps what is happening is that the total size of your DLL + your static variables is hitting a limit.  These things are all put in a single chunk of memory by the operating system when it loads your DLL.  The limit could be one associated with the file format used for DLL's, EXE's, etc of about 2 GB, or one associated with the need to find a contiguous chunk of memory big enough to hold the code plus static data (given you are sharing your address space with Excel - that could be a challenge).

Again, guessing, but when you statically link the runtime to your DLL, you make the code of the DLL larger (because code formerly in the runtime DLLs is now in your DLL - hence the amount of space available for static variables has to shrink.

If you change your variables to be allocatable, then, when allocated, they can be placed in memory separately to the code for your DLL.  This means that they no longer count both for the file format limit of 2 GB and can also be fitted into perhaps smaller free gaps in the address space.

(In addition to this being a bit of a guess, my knowledge of the low level memory management games is also subject to considerable error.)

Thanks IanH,

I agree with your explanations. Since the only difference between the two DLLs is the Runtime library used, this must have changed the memory available for the static variables I guess.

Thanks very much.

Regards,

Jackie

I have looked for this answer for days, and have tried nearly every goofy thing people have proposed, but this one line of yours saved my life.

Thanks,

Noji Ratzlaff

Quote:

David White wrote:

Just be aware, that if your end users have a 64-bit version of Office, then they cannot use the 32-bit DLL's.  Excel in this case will report that the DLL is not found, even if it is on the path.  The correct message should be that it is unable to load the DLL.

Thanks Noji,

Even though I know this problem exists, when a new user contacts me saying my apps won't run on their machine, often the last question I think of asking is whether they are using 64-bit Office!  I normally go through my normal suite of debugging checks before tripping over this one.

David

Leave a Comment

Please sign in to add a comment. Not a member? Join today