LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW 64-bit built application crashes when calling user32.dll

Solved!
Go to solution

I'm not able to call any function in the user32.dll in a built 64-bit application, in that case the application crashes. Attached is a a project with a very simple VI that calls GetCursorPos function in this dll, in the development environment it's running ok but when building an application it crashes at startup.

hunkel_0-1642602727642.png


Isn't it possible to call this dll in 64-bit? The selected user32.dll is in C:\Windows\System32 directory

(LabVIEW 2020 64-bit)

0 Kudos
Message 1 of 4
(1,199 Views)
Solution
Accepted by topic author hunkel

Got some help from the NI support. The solution was to change how the dll is referenced in the node. If set to just the name (user32.dll in this case) it's working, but if set to full path (i.e. C:\Windows\System32\user32.dll) it's crashing. According to this article both should be ok so it seems like this is a bug though.

0 Kudos
Message 2 of 4
(1,139 Views)

@hunkel wrote:

Got some help from the NI support. The solution was to change how the dll is referenced in the node. If set to just the name (user32.dll in this case) it's working, but if set to full path (i.e. C:\Windows\System32\user32.dll) it's crashing. According to this article both should be ok so it seems like this is a bug though.


Actually, the link states that "Either of the latter two will prevent this crash."  (The "latter two" are: specifying a relative path using windows environment variables or just using the name itself.)  The reason is that when you use the relative path or the name by itself, Windows gets to determine which version to use, but by specifying the absolute path, you take that choice out of the hands of the operating system.  (Don't ask me why this is true - it would seem that an absolute path should work, but that's just another Windows mystery.)  These two ways are better at any rate because they make the code "bitness-agnostic" which means it will run in either 32-bit or 64-bit LabVIEW.

 

Edit: I think maybe C:\Windows\System32 might actually be a symbolic link, which would explain why it won't work right.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 3 of 4
(1,128 Views)

@hunkel wrote:

I'm not able to call any function in the user32.dll in a built 64-bit application, in that case the application crashes. Attached is a a project with a very simple VI that calls GetCursorPos function in this dll, in the development environment it's running ok but when building an application it crashes at startup.


Isn't it possible to call this dll in 64-bit? The selected user32.dll is in C:\Windows\System32 directory

(LabVIEW 2020 64-bit)


The problem is that with an absolute path the application builder assumes that it is a DLL that needs to be copied into your application directory (more specific in the data folder inside it). And the VI in the executable is modified to reference this new private copy.

 

Now these Windows dlls can not be loaded from multiple locations at the same time on a machine since they do all kinds of internal trickery with respect to resource handling such as windows handles and many many more handles.

 

So your exe loads that private DLL and then your LabVIEW app hands it a windows handle or similar that it got from a different system call in another DLL and your private copy barks (hey that's not a valid handle that I know off, and booom!)

 

By specifying only the DLL name LabVIEW will still be able to load that DLL since the Windows DLL loader will search for it in its well known locations (and also adjust those locations properly for 32-bit and 64-bit applications). And the LabVIEW application builder knows that this is a system DLL that should not be copied into the application directory and the VI inside the application is NOT modified to refer to this private copy.

 

Now when starting the application everything is fine.

 

Also there is another reason NEVER to copy those Windows system DLLs into your private application directory: They can be very specific to a certain system version, including knowledge base bug fixes etc. So the system DLL from your development system has a serious chance to NOT work on another system even if the Windows version seemingly is the same.

 

And if you ask why the application builder makes this "strange" distinction then the answer is that there is no perfect way to determine if a DLL is a system DLL. The application builder could try to determine the path of a DLL and compare its directory with a number of known directories, but those directories are not consistent between Windows versions and can even be customized during Windows installation so fixed paths are not an option. And the Windows API does provide ways to retrieve some of those paths but not all, so it would be a pretty performance hungry solution that still misses some potential "system" DLLs.

 

When an application passes an absolute DLL path to the LoadLibrary() function Windows will try to load the DLL from that location and if that fails for any reason it returns an error and will NOT try to load it from elsewhere. When only a relative path is passed (or just the name) then Windows will go and search through its well known locations and try and load that DLL from there. So LabVIEW is pretty much using the Windows definition of how private and system DLLs are addressed.

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 4
(1,120 Views)