LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Find path of dll in Library Node Function

Solved!
Go to solution

@rolfk wrote:

Nice work, but my eyes hurt when I see the module name wire not lining up to the arg1 parameter (which could be named more descriptively too). Smiley LOL


Agreed. That does hurt my eyes too. Of course, I didn't notice until I posted it...

 

This is better:

Get Loaded DLL Path.png

 

I took a bit of liberty with the naming of the return values. The GetModuleFileNameA return value is actually the number of characters copied into the string. But that wouldn't be used much in LV, so Success? makes sense to me.

 

Some error handling would be nice, but to get the error, a call to GetLastError is needed, and that's a pain. And AFAIK not thread safe. A quick check on the return values could be used to set a fixed error message though.

 

Now all the VI needs is a VI description and Control\Indicator descriptions. And depending on who you'd ask, an image for an icon. I'll stick with text...

Message 11 of 15
(602 Views)

wiebe@CARYA wrote:

@rolfk wrote:

Nice work, but my eyes hurt when I see the module name wire not lining up to the arg1 parameter (which could be named more descriptively too). Smiley LOL


 

Some error handling would be nice, but to get the error, a call to GetLastError is needed, and that's a pain. And AFAIK not thread safe. A quick check on the return values could be used to set a fixed error message though.

 


Well thread safe might be not the right naming here. It won't crash or anything because you call the GetLastErrror() function, it just most likely won't return the error code that you want.

 

Windows maintains a lastError value per thread, so by using Call Library Nodes in multithreading configuration it means they can be called in any of the threads inside the current LabVIEW execution subsystem, and that could be therefore a different thread than the one the function generating an error might have been called.

 

Changing all the Call Library Nodes back to run in UI thread is also not a solution as the code execution shares this thread with anything else that LabVIEW wants to do in the UI thread including (yes you guessed it, the entire UI drawing and whatever). So between the function causing an error and your GetLastError() call there could be many other Windows API calls that overwrite the lastError value in that thread.

 

There is a solution to this however: Leave the nodes configured to be executable in any thread and configure the VI to be of subroutine priority. It will disable debugging for the VI, so make sure your VI works well, but subroutine proirity has one specific interesting attribute that helps here: it guarantees that the entire VI will be executed in one go inside the same thread, without any thread scheduling in between. It makes the VI in principle one big individible code clump that the LabVIEW scheduler is not allowed to break up into smaller code clumps to execute.

 

You can not call asynchronous code (Wait and similar functions) inside such a VI and also nothing that requires the UI thread in any way.

 

In this specific case I would just do the entire VI as subroutine and add the necessary GetLastError() calls in between but in a more generic library I would start creating subVIs for just one or two Windows API calls with the necessary GetLastError() calls to avoid creating huge subroutine monsters that hog down the thread entirely and work against LabVIEWs intelligent multithreading management. 

Rolf Kalbermatter
My Blog
0 Kudos
Message 12 of 15
(597 Views)

For this VI, I'd probably just add fixed LabVIEW errors for each function for now, based on their return values.

 

GetLastError could\should be followed by a FormatMessage to get a text description, adding even more work to a simple set of functions.

 

I've used GetLastError in the past, but mostly during testing. For this VI, I don't thing there will be enough reasons for errors to put much effort in adding GetLastError.

 

Of course, time could prove it is needed for this VI.

0 Kudos
Message 13 of 15
(591 Views)

I fully agree that there is not really more needed for this particular VI. It's a simple function that can fail for a number of reasons but all that is interesting is if it did fail in any way or not. Not much use in getting more detailed here.

 

I was just responding in general to your remark about using GetLastError(). It is tricky but there is a proper and working method to do it. And it's not relaying on undocumented LabVIEW features either!

Rolf Kalbermatter
My Blog
0 Kudos
Message 14 of 15
(588 Views)

I want to add a different approach to Heartbeat's question. Jacobson already approached it a bit, however I have a more general solution:

Wiebe's and Rolf's solution is very good, if you can access the LabVIEW code and/or know exactly what dll you are looking for. Assuming your "new" code will do the same like the one you are troubleshooting, this will definitely work, and is a very convenient solution.

But what do you do when you have compiled code and simply don't know that function / dll is missing, so you can't look it up?

Well, there is Sysmon, one of the utilities from Microsoft's Sysinternals suite. It can log which drivers and/or DLLs a program (tries to) load. It needs to be set up to filter what you want to see, but it can tell you on a much lower level what you program is actually trying to do.


Ingo – LabVIEW 2013, 2014, 2015, 2016, 2017, 2018, NXG 2.0, 2.1, 3.0
CLADMSD
0 Kudos
Message 15 of 15
(581 Views)