LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Missing external function in third party .dll

Solved!
Go to solution

I am trying to build an application to talk to the Tektronix RSA306B USB spectrum analyser.

 

It supposedly had a Labview driver that came with it, but it was nothing more than instructions on how to build the library from the supplied API, i.e. their third party RSA_API.dll file.

 

So I've built a library, and built a VI that can talk to and get data off the spectrum analyser by calling the library functions, but when I try to deploy it of my development machine (Win 10) it all goes wrong.

 

I've built an executable (LV runtime is already installed and can run other built executables), I've built an installer multiple times with different settings, but I always get the same result - a broken run arrow and the list of all the functions from the API, for example:

 

Missing External Function RSA_API.dll:DeviceSearch:C in RSA_API.lvlib:DEVICE search.vi

 

The .dll is definitely in the \data directory.  I've run out of ideas as to what I'm missing.  Is there a way to set a path variable somehow?

0 Kudos
Message 1 of 15
(3,760 Views)

@HotDang wrote:

The .dll is definitely in the \data directory.  I've run out of ideas as to what I'm missing.  Is there a way to set a path variable somehow?


There is, but it won't help much. \data (presuming it's under the exe) is searched by the exe, just like all sub directories of the exe's path.

 


@HotDang wrote:

So I've built a library, and built a VI that can talk to and get data off the spectrum analyser by calling the library functions, but when I try to deploy it of my development machine (Win 10) it all goes wrong.


Does that mean the installed exe works on the development machine?

 

It sounds like RSA_API.dll has a dependency that's missing. Could be something low level as a c runtime dll...

 

You could try something like Dependency Walker to check the dll's dependencies. See if there's one missing on the non-development PC.

 

 

Message 2 of 15
(3,734 Views)

Thank you for your response.

 

Didn't think to try running the .exe on the development machine.  And no, it doesn't run, it has the same issue 😞

However, that makes my testing cycle much quicker, I can just test on the dev machine rather than have to copy it over to the target machine every time 🙂

 

I tried the dependency walker on the development machine, and couldn't even see where my executable calls that .dll.  Strange.

 

I'm wondering if it has something to do with the source file settings for the dependencies?  I've tried multiple combinations without success.

 

That said, I'm not building an installer at the moment, just an exe.

 

 

HotDang_0-1661239148955.png

HotDang_1-1661239209340.png

 

 

0 Kudos
Message 3 of 15
(3,700 Views)

Could it possibly be a 32/64 bit issue?  I'm compiling with a 32 bit environment and the dll was from the x86 directory.

 

Also, I've just downloaded the new 2022 Q3 version, and trying with that but same issues.

0 Kudos
Message 4 of 15
(3,698 Views)
Solution
Accepted by topic author HotDang

@HotDang wrote:

 

I tried the dependency walker on the development machine, and couldn't even see where my executable calls that .dll.  Strange.


Dependency Walker can't see the dependencies you add in your code through the Call Library Node (and several others that LabVIEW loads dynamically to) of a LabVIEW executable. That is because LabVIEW has to link to the external libraries explicitly by calling LoadLibrary(), not through some import link library that adds the imports to the executable image. If it would use static linked import libraries for everything you couldn't even startup the executable if even a single of those DLLs doesn't exist on the system, even if it is never executed. 

 

You need to check the DLL itself in Dependency Walker. That will tell you if the system can't find a specific DLL that your main DLL depends on. My guess is that there are other DLLs that it depends on and that you have in your project directory alongside the main DLL when you run in the development environment. LabVIEW doesn't know about these dependencies and shouldn't even want to know. Such trickery would only result in even more obscure problems. What LabVIEW does when you run your VI from within a project is to register the project directory as extra directory for Windows to search for additional DLLs. This is since it would be very bad practice to have to copy such DLLs into the LabVIEW.exe directory. This locations should be considered read only at all times.

When you build an executable there is no such project directory anymore. LabVIEW by default puts all the DLL dependencies it knows about (because they are referenced from inside a Call Library Node) into the data directory. The extra dependencies it doesn't know about and you have to make sure yourself that they are findable by Windows. There are a few specific locations that Windows will search and the first of all them is the directory in which the executable is located that started the current process. Not the data subdirectory that LabVIEW by default uses to put support files into!

You can leave the directly referenced DLLs in the data subdirectory but you have to copy the additional dependencies into the same directory that your exe is placed into. And you can easily let the exe Builder step do that.

 

1) Create a folder in your project where you add all these DLLs

2) Create a destination in the Build script that is for instance called Dependencies and point it to the main directory where your executable is placed too

3) Add this Dependency folder as Always Included to the build instructions

4) Build your executable

 

Now you should have those additional DLLs present in the executable directory. If you want to get fancy you can also start customizing the default support folder and remove the LabVIEW found DLLs from it and add them to the Dependency folder too. It's cleaner to put all depending DLLs of your executable into this folder but not required. LabVIEW remembers the location where it build the DLLs into and adapts during build the paths in the Call Library Nodes to point to that relative path.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 5 of 15
(3,684 Views)

@HotDang wrote:

Could it possibly be a 32/64 bit issue?  I'm compiling with a 32 bit environment and the dll was from the x86 directory.

 

Also, I've just downloaded the new 2022 Q3 version, and trying with that but same issues.


If this isn't a problem in development, it shouldn't be a problem in the exe.

Since you run the exe (after a copy? from a network?), maybe double check if the dll is unblocked:

.dll file won't load - How to unblock a dll file? - CloudShell Community (quali.com)

 

I doubt that this is the problem. The dll seems to load, somehow LV doesn't see the functions...

0 Kudos
Message 6 of 15
(3,674 Views)

wiebe@CARYA wrote:

I doubt that this is the problem. The dll seems to load, somehow LV doesn't see the functions...


Well Windows for some reasons refuses to load the DLL. And the most common reason is that it can't resolve a dependency. In a long ago past LabVIEW tried to make the error message more specific by trying to load the DLL as a data file if Windows refused to load it. This was to distinguish between if the DLL file itself was not present or if loading failed because of some unresolved dependencies. For some reason this was removed at some point and the error message was generalized to say that the DLL or one of its dependencies couldn't be found. I assume this was because with different Windows versions such specific error handling got difficult to manage consistently and rather than trying to figure out how to make this detection more version resilient, it was simply removed as any algorithme that may have worked with a new Windows version could have been rendered useless with the next Windows release or even security update. To rely on specific behaviour that isn't explicitly documented by Microsoft for a specific function is always a tricky endeavor and a source of potential confusion.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 7 of 15
(3,652 Views)

Hi Rolf,

 

Thank you very much for your detailed explanation.  I think I (or rather you!)  have found the problem.  There were several other Tektronix DLLs that were alongside the RSA_API.dll.  Copying those into the data directory seems to have fixed it on the dev machine, looking forward to seeing if that makes it go on the target.

 

Daniel.

0 Kudos
Message 8 of 15
(3,631 Views)

If the Tektronix DLL does some custom handling of its own to look for the dependent DLLs in the same directory than itself this can work. But the "data" directory is not generally a directory that Windows would know about at all and hence would not search on its own. So unless something changed in a recent LabVIEW version where the runtime would add this data directory explicitly as additional search path to the Windows search paths, I would recommend to generally place those dependent DLLs in the same directory as the exe file. This is a standard Windows search location so will always be found in there independent of custom DLL handling in loading its own dependencies or used LabVIEW version.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 9 of 15
(3,619 Views)

@rolfk wrote:

wiebe@CARYA wrote:

I doubt that this is the problem. The dll seems to load, somehow LV doesn't see the functions...


Well Windows for some reasons refuses to load the DLL. 


But it loads the dll, it can't find the exported functions.


When a dll can't be loaded, you usually get another error.

0 Kudos
Message 10 of 15
(3,598 Views)