LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DLL function doesn't work when being called from LabView using Call Library Function

Solved!
Go to solution

Hi,

 

I have a DLL function I'm trying to call from LabVIEW. I've successfully called this initialisation function InitAPI using a unit test and it returns an OK status (1). However, when I try to run the same function using the Call Library Function in LabView it returns an error status (2002 - Error Loading Communication Layer). I'm not sure precisely what the error means, but i think it might have something to do with the CommunicationLayerWindows.dll.

 

I've attached my VS2019 solution along with my test VI (found in Kinova LabVIEW Interface\Debug). Please let me know if you need anything else.

 

Many Thanks

 

0 Kudos
Message 1 of 13
(1,047 Views)
Solution
Accepted by topic author ralphieraccoon

It's likely very simple. Where did you put your KLInterface.dll, CommandLayerWindows.dll and CommunicationLayerWindows.dll?

 

Unless they are in the root directory of your application they likely can't be found by Windows. While you define the full path to the KLInterface.dll in the LabVIEW Call Library Node and LabVIEW passes that to Windows you only pass the DLL name for CommandLayerWindows.dll to LoadLibrary() and this DLL most likely does the same for CommunicationLayerWindows.dll. In that case the Windows LoadLibrary() function will search for DLLs in some well defined locations but nowhere else.

 

When you build your C test application all those files are copied into the same build directory so the DLLs land besides your EXE file and all is fine. To get the same effect you need to copy all the DLLs except the ones you directly reference through the Call Library Node into the LabVIEW.exe directory, however that is a very bad and unmaintainable solution. Instead, those DLLs should be installed in a well known location by an according installer.

Rolf Kalbermatter
Averna BV
Message 2 of 13
(1,004 Views)

Hi Rolf,

 

They're all in the same directory, including the VI. I was hoping that would avoid any search path issues. I guess I could try adding the directory to PATH and see if that works.

 

Many Thanks

0 Kudos
Message 3 of 13
(1,000 Views)

PATH should work but is a bit of an ugly solution if you ever intend to distribute your VI or a built app to other computers. Windows knows nothing about VIs so can’t reference the directory of that VI for a search and LabVIEW knows nothing about the interna of your DLLs and that this DLL may attempt to call a myriad of other DLLs. 

Also I fail to see the need for the wrapper DLL you create, but haven’t checked all functions in the header file. The Call Library Node should be able to interface to CommandLayer DLL directly too for the few functions you try to interface to in your DLL.

Rolf Kalbermatter
Averna BV
0 Kudos
Message 4 of 13
(968 Views)

Unfortunately they're not my DLLs, I don't have the source code for either they're just lifted from the SDK along with the headers. So I've got no idea where or how InitAPI in CommandLayer pulls functions from CommunicationLayer, only that it does seem to based on the error. I'm not experienced enough in DLL dependency unfortunately to know if there is an alternative to using PATH.

 

I tried adding to PATH earlier and it seems to work. I need to investigate a bit further tomorrow (though it's my last day in the lab this year, so I won't have much time!). As for the necessity of a wrapper DLL, it might not be essential but there are some structs I have to deal with that may make things a bit more messy (GetDevices outputs a 1D array of KinovaDevice struct), so a wrapper may make things simpler.

0 Kudos
Message 5 of 13
(955 Views)

I'm wondering if AddDllDirectory or SetDllDirectory would work in this case. I will have a go when I get the time.

0 Kudos
Message 6 of 13
(942 Views)

@ralphieraccoon wrote:

I'm wondering if AddDllDirectory or SetDllDirectory would work in this case. I will have a go when I get the time.


It likely will but wasn't available in early Windows 7 systems. And read the Notes section on MSDN.

 

AddDllDirectory() only works for LoadLibraryEx() using the LOAD_LIBRARY_SEARCH_USER_DIRS flag. Since you can't control what functionality your 3rd party DLL uses to load its secondary dependencies you first also have to call SetDefaultDllDirectories() with that flag. And of course reset everything nicely after you are done initializing the main DLL. Messing with the DLL search order can have serious side effects that you want to try to minimize as much as possible.

Rolf Kalbermatter
Averna BV
0 Kudos
Message 7 of 13
(933 Views)

The only other alternative I can think of is to do a DLL redirection in a manifest. Would that be a cleaner solution (If it would work)?

0 Kudos
Message 8 of 13
(925 Views)

I never worked with manifests beyond elevation settings and have a hunch that DLL redirects through manifests is not solving a problem but adding several more.

Rolf Kalbermatter
Averna BV
0 Kudos
Message 9 of 13
(920 Views)

Fair enough, thanks again for all your advice so far. Given I cannot change the source code of either DLL, what do you think would be the most elegant solution? I don't think any option is going to be ideal here because I'm not Kinova.

0 Kudos
Message 10 of 13
(917 Views)