LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Calling my DLL: "Library not found or failed to load" after recompile

Solved!
Go to solution

Scenario: I am writing a little C code library to be called from LabVIEW. I build my DLL and create a test VI with a Call Library Function Node. I configure it, it runs, it works.

Close the VI, make changes and rebuild the DLL. Reopen the VI. It shows a broken arrow. This reveals the error  "Library not found or failed to load". Open the configuration, re-select the DLL, re-select the function within the DLL from the pulldown menu. It's there, nicely smiling, making me believe that everything is going to be okay. Close the configuration, and nothing has been fixed.

 

I tried going back to EXACTLY the previous state of the C code and rebuilding the DLL again; nothing was improved.

 

The only solution I have found that sometimes works is to delete the Call Library Function Node and re-create it from scratch. That's going to be a long, tedious development cycle! Any help? My C code, my DLL, and my VI are attached. (And by the way, it doesn't read from Excel, I'm not even dealing with that complexity until I can reliably call the DLL! To the best of my knowledge it has no external dependencies except perhaps the C runtime library itself.)

Download All
0 Kudos
Message 1 of 9
(2,549 Views)

Does your DLL rely on another DLL (such as a DLL containing the functions declared in your libxl.h file) that you by any change put into the same directory as the DLL you try to call from LabVIEW?

 


@Ken_Brooks wrote:

 

The only solution I have found that sometimes works is to delete the Call Library Function Node and re-create it from scratch. That's going to be a long, tedious development cycle! Any help? My C code, my DLL, and my VI are attached. (And by the way, it doesn't read from Excel, I'm not even dealing with that complexity until I can reliably call the DLL! To the best of my knowledge it has no external dependencies except perhaps the C runtime library itself.)


That may look like that since you commented out the code in the C file that calls the libxl functions but we haven't seen your header or project file. There could be very well definitions in there that are pulled into the source code no matter what and cause your DLL to be referenced anyhow such as a lib statement that defines the import library to link into the compiled dll or a project setting for the libxl.lib file.

 

Looking in dependency walker your DLL definitely references:

 

libxl.dll

vcruntime140d.dll

ucrtbased.dll

 

The two latter are debug versions that are only available on computers where you have Visual Studio 2015 installed. The first VERY much looks like your Excel interface DLL. 😀

 

What happens here is that LabVIEW asks Windows to call the ReadExcel.dll and Windows sees that it probably requires the libxl.dll (or whatever it is called). Windows only searches certain locations for DLLs and aside from the <Windows> and <System> directory as well as the directory in which the executable is located that started the current process, it also searches in the <current directory>. This is a remainder of the old single threaded DOS execution model and is pretty much an anachronism that survived all the time in Windows for various backwards compatibility reasons. An "interesting" feature of Windows is that this directory gets updated for the current process whenever the user dismisses the Windows file dialog with the OK (Open, Save, Select) button the whatever directory the user was in at that moment. So you browsing in LabVIEW to the directory with your own DLL will set the current directory to that directory and suddenly Windows can find the libxl.dll that your own DLL references.

 

Solution is to copy that DLL to some other location that Windows will search automatically. 

Rolf Kalbermatter
Averna BV
0 Kudos
Message 2 of 9
(2,480 Views)

So Rolf, you saw that I commented out all the code relating to LibXL.  How then did that dependency survive?  Are these things "sticky" in VS?  Also, I built my dll in Labview 2017, but you found a C Runtime reference to Labview 2015.  How could that have happened??

 

And what is the best way to make this C code library product-quality robust, so it will for sure load properly on customer machines where it will be installed?

 

>>> Solution is to copy that DLL to some other location that Windows will search automatically. 

Do you mean my ReadExcel.dll, or libxl.dll, or both?

0 Kudos
Message 3 of 9
(2,420 Views)

So you inspired me to go and learn how to use Dependency Walker. I gave it a try. Behold. I see the libxl.dll dependency, but I also see strange error reports under Kernel32.dll that, if they were true, my system would surely be inoperable! A similar list shows for UCRTBASED.DLL. Not only that, but the icon beside kernel32.dll shows a 64 as if it were a 64-bit DLL. Does that make any sense??

Dependency walk ReadExcel.dll.jpg

 

I tried copying libxl.dll into \Windows\System32. It still didn't make my dll happy to load. Although if I build a dll without any dependency on libxl, it loads fine! Is there any way to get more detailed diagnostic information out of the loading process, to figure out what exactly it is choking on?

0 Kudos
Message 4 of 9
(2,409 Views)

@Ken_Brooks wrote:

So Rolf, you saw that I commented out all the code relating to LibXL.  How then did that dependency survive?  Are these things "sticky" in VS?  Also, I built my dll in Labview 2017, but you found a C Runtime reference to Labview 2015.  How could that have happened??

I never said anything about a LabVIEW 2015 C runtime. The vcruntime140(d).dll is part of the Visual Studio 2015 C Runtime Library. If you use Visual Studio 2017 you have set in your project to target the vc14 runtime somehow.  

 

There are various possibilities to reference the libxl.dll somehow. It could be that you still listed the libxl.lib file in the linker settings of your project and then Visual Studio may still link it into the DLL eventhough it's not referenced at all. Or you use incremental compile and the reference from an earlier attempt still was in the compiler output directory and got picked up somehow. Or, or, or, ..... 

 

And what is the best way to make this C code library product-quality robust, so it will for sure load properly on customer machines where it will be installed?

 

>>> Solution is to copy that DLL to some other location that Windows will search automatically. 

Do you mean my ReadExcel.dll, or libxl.dll, or both?


No ReadExcel.dll is referenced by the Call Library Node by path and will be loaded with that full path so LabVIEW won't have trouble to load that. But LabVIEW knows nothing about the libxl.dll dependencies and shouldn't even try to know. That would be a very nasty rabbit hole when applications try to second guess Windows dll dependency loading.

 

So you inspired me to go and learn how to use Dependency Walker. I gave it a try. Behold. I see the libxl.dll dependency, but I also see strange error reports under Kernel32.dll that,

if they were true, my system would surely be inoperable! A similar list shows for UCRTBASED.DLL. Not only that, but the icon beside kernel32.dll shows a 64 as if it were a 64-bit DLL. Does that make any sense??

Dependency Walker is an older application which has not been updated to properly work with 32-bit/64-bit references as well as with the so called SxS (side by side) technology Microsoft invented for Window Vista to circumvent DLL hell by creating DLL chaos! 😀

 

So the results it shows in terms of what 32/64 bit DLL is loaded is only partly correct. It tends to only look in the system directory for the bitness the Dependency Walker was itself compiled for and therefore gets them wrong if you analyze a DLL with a different bitness. And the modularization of the Windows kernel DLLs in Windows 7 into submodules it can't correctly handle either. Just ignore them. The principle about what DLLs are referenced is still correct.

Rolf Kalbermatter
Averna BV
0 Kudos
Message 5 of 9
(2,403 Views)

 

The plot thickens. I tried copying my DLL, ReadExcel.dll, into C:\Windows\System32. Seen from a folder window, it is there just fine. Then I go to load it from this location into a LabVIEW call node. From the file picker, I cannot see it there! Nor libxl.dll. I see a set of files that is partially overlapping but in no way identical to the set of files shown in the folder window. As if I had stumbled upon a shadow copy of the System32 directory! Screenshot included below. Have you ever heard of such a thing?

 

Either window has files the other does not.Either window has files the other does not.

 

 

0 Kudos
Message 6 of 9
(2,402 Views)
Solution
Accepted by topic author Ken_Brooks

On 64-bit Windows, System32 is for 64-bit DLLs, and SysWOW64 is for 32-bit DLLs. I know it sounds mixed up, but that is how it is. If a 32-bit app passes a path to System32 to a file function, Windows in its great wisdom will redirect that to SysWOW64 instead and vice versa for a 64-bit application trying to access SysWOW64.

 

So put your 32-bit DLL in the SysWOW64 folder and in the Call Library Node only enter the DLL name without any path. LabVIEW will request Windows to load that DLL name and Windows will find it in SysWOW64. Also since you only specified the name in the Call Library Node LabVIEW will NOT copy the DLL into the build application folder but simply expect that the ReadExcel.dll is findable by Windows on any target system. While referencing the ReadExcel.dll with full path is possible (and LabVIEW would then copy that DLL into the support folder in the build directory too) you have to make sure that libxl.dll is findable by Windows since LabVIEW knows nothing about this.

 

You could explicitly add libxl.dll into the build and make sure it gets copied into the same directory as your buildApp.exe file. That is another location Windows will search when trying to find a DLL by name. Or you can create an installler for your ReadExcel.dll and libxl.dll and make sure to install them into the relevant System folder.

Rolf Kalbermatter
Averna BV
Message 7 of 9
(2,398 Views)

At last! I can get LabVIEW to accept my DLL!

But if I needed my fix of weirdness for the week I got it today. That SysWOW64 business is REALLY weird. There actually is a shadow copy of the directory!

 

I'm still a little bit mystified on this:if

You could explicitly add libxl.dll into the build and make sure it gets copied into the same directory as your buildApp.exe file. That is another location Windows will search when trying to find a DLL by name. 

 

I suppose you are talking about if I built my LabVIEW program into an app? Because that probably isn't going to happen in this project anytime real soon. So is there no other way to put a pair of DLLs, one depending upon the other, into a directory of MY choosing and have them load correctly?

0 Kudos
Message 8 of 9
(2,368 Views)

Yes I was talking about when you build an application. For your development system you have three useful locations that you could use.

1) System directory. Watch out to put it in the correct bitness folder!. This is however not ideal as you are cluttering your already HUGE system directory with non system files.

2) LabVIEW directory (where your LabVIEW.exe resides), similar as 1)

3) An arbitrary directory whose path you add to your environment variable PATH. This is usually the cleanest solution but requires an additional step to modify the environment variable.

But Windows has a length limit for environment variables. You can make them longer without any indication that there is a problem an they seem to be as long as you set them when checking them but.once you reach that limit (around 1000 or 4000 characters, not sure anymore) Windows starts to behave very erratical when you try to launch command line programs and other programs that somehow use the PATH variable, giving you weird errors about not finding important subcomponents

Rolf Kalbermatter
Averna BV
0 Kudos
Message 9 of 9
(2,360 Views)