LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Capturing STOUT/STDERR from C DLLs


wiebe@CARYA wrote:

I think the DLL itself can redirect it's outputs (to a named pipe). So I think you could make a function that set's up the redirection. Then, the rest of the dll could stay the same?


The redirect won't need to re-setup each time I call into the DLL?  I'd assumed that it would.  I'll test that.

0 Kudos
Message 41 of 47
(1,804 Views)

This actually appears to work with my test case.  If I just make a call into the dll to setup the redirect, then it appears as though the rest of the calls into the dll will have their stdout routed to the pipe I'm reading. 

 

This I believe resolves my issue. 

 

Thank you again.

 

 

0 Kudos
Message 42 of 47
(1,794 Views)

@scorn001 wrote:

This actually appears to work with my test case.  If I just make a call into the dll to setup the redirect, then it appears as though the rest of the calls into the dll will have their stdout routed to the pipe I'm reading. 

 

This I believe resolves my issue. 

 

Thank you again.

 


The DLL stays the same process once it's loaded. So that is why it works. It will probably only work if the VI is set to run in UI thread. I think running in other thread instantiates new instances for each time you use it (not sure might test that).

 

Could you post the code of the function in the DLL? I think it would help out a lot of people in the future.

0 Kudos
Message 43 of 47
(1,786 Views)

wiebe@CARYA wrote:

The DLL stays the same process once it's loaded. So that is why it works. It will probably only work if the VI is set to run in UI thread. I think running in other thread instantiates new instances for each time you use it (not sure might test that).

 


That doesn't sound quite right. A specific DLL is only mapped once into a process. Unless it uses a SxS (side by side) configuration, only the DLL name is important for Windows to decide if a DLL is already mapped into a process space. With SxS a DLL can be loaded multiple times into the process, once for every version of the DLL that some part of the application links to.

And the Standard C stdio fd's are most likely also C runtime library global but as explained earlier you can easily end up with multiple C runtime libraries linked into the same application. This has also other consequences such as not being able to pass memory pointers allocated in the context of one C runtime library to a context that links to a different C runtime library to deallocate this pointer. Same applies for file descriptors opened with C runtime library functions.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 44 of 47
(1,781 Views)

wiebe@CARYA wrote:

The DLL stays the same process once it's loaded. So that is why it works. It will probably only work if the VI is set to run in UI thread. I think running in other thread instantiates new instances for each time you use it (not sure might test that).


That doesn't sound quite right. A specific DLL is only mapped once into a process. Unless it uses a SxS (side by side) configuration, only the DLL name is important for Windows to decide if a DLL is already mapped into a process space. With SxS a DLL can be loaded multiple times into the process, once for every version of the DLL that some part of the application links to.

And the Standard C stdio fd's are most likely also C runtime library global but as explained earlier you can easily end up with multiple C runtime libraries linked into the same application. This has also other consequences such as not being able to pass memory pointers allocated in the context of one C runtime library to a context that links to a different C runtime library to deallocate this pointer. Same applies for file descriptors opened with C runtime library functions.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 45 of 47
(1,779 Views)

@Rolfk:

 

So you're saying (among other things) that "run in any thread" would not make a difference? That it should work (but obviously might "mix" results)?

 

I thought "run in any thread" had a re-entrant like effect (separate memory space). Haven't given it much thought lately tough. If I understand correctly it only enables parallel execution. That does make more sense.

 

I guess at least "specify path on diagram" could be tricky, because LV might unload the dll if it's not used anymore? I think LV only unloads dll's when the call library node is called with another path.

0 Kudos
Message 46 of 47
(1,760 Views)

Run in any thread really only means that the Call Library Node is free to execute in whatever thread the VI is at that moment executing (and that will consume that thread exclusively for the function call until it returns back to LabVIEW as LabVIEW can't do its cooperate multitasking magic during the Call Library Node call, it doesn't have any hooks into the DLL to suspend its execution and assign the thread to other code clumps to execute).

As far as LabVIEW is concerned the DLL function is a complete black box that gets passed the input parameters on the stack (some registers too for 64 bit) and at some point returns with an optional  integer return value in the EAX (or RAX for 64-bit) register, or the ST0/IMM0 register for floating point return values. For output parameters (parameters wired on the right side of the Call Library Node and defined as reference parameters in the C code) the parameters then returned back to the diagram.

 

Nowhere is any LabVIEW specific reentrancy (memory space) involved unless you start to play with the Callback functions in the Call Library Node configuration dialog and use the InstanceDataPtr in the call to your Call Library Node.

 

But functions that are called from any thread need to be fully reentrant capable to be safe to be called in that way, although that is not a strict requirement if you can guarantee in other ways that no global resource can be accessed concurrently by multiple/concurrent calls to any function in a DLL. But proofing that for not fully reentrant functions is anything but trivial and also usually hard to enforce for a casual LabVIEW programmer who is going to use your LabVIEW VI library in many very obscure ways.

 

Distributing a VI library that has the requirements that you have to call all the functions sequentially through some means like error cluster wiring in order to not crash is not very user friendly. Smiley Very Happy On the other hand that you have to start a data acquisition successfully, before you can expect to retrieve any meaningful data without getting an error is of course quite logical but that is not what this discussion is about. Returning an error because certain prerequests have not been fullfilled is fully legal, but crashing because of that is not!

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 47 of 47
(1,756 Views)