LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Capturing STOUT/STDERR from C DLLs


@scorn001 wrote:

I really appreciate you putting in all this effort to help me with this.  If I haven't said thank you before - thank you.


You're welcome. The reason I (and Rolfk I presume) help you on this one, is that is getting this to work is useful for us too.

 


scorn001 wrote:

I rebuilt, removing all of the other unused routines.  This should just contain a single printstuff routine.


The dll still gives the same error (with dynamic path). I think I need a C runtime or something.

0 Kudos
Message 31 of 47
(1,733 Views)

@scorn001 wrote:

Also, Console.Write does work and produces output in the Read loop.


So this must mean Console.Write uses another StdOut then the printf in the dll?

0 Kudos
Message 32 of 47
(1,732 Views)

@rolfk wrote:

wiebe@CARYA wrote:

The dll fails to load:

 

LabVIEW:  Failed to load dynamic library because of missing external symbols or dependencies, or because of an invalid file format.


You don't have the Visual C  Runtime redistributable files installed that correspond the the Visual Studio version that was used to create the DLL!


Figured as much. My post crossed your.

0 Kudos
Message 33 of 47
(1,730 Views)

BTW. I checked Console.Write with an AllocConsole (use FreeConsole to remove this window).

 

Using Console.Write does output to this console. (You do need a restart if you redirected the StdOut.).

 

Can you check if your dll outputs to a fresh AllocConsole window?

0 Kudos
Message 34 of 47
(1,728 Views)

wiebe@CARYA wrote:

@scorn001 wrote:

Also, Console.Write does work and produces output in the Read loop.


So this must mean Console.Write uses another StdOut then the printf in the dll?


Absolutely!

 

That are the _open_osfhandle() and _fdopen() calls in the C code example. And if you happen to compile your C++ code with the cpp compiler you also need to add a call to ios::sync_with_stdio() after you mapped the C runtime stdio fds to the process stdio handles otherwise the C++ template printf routines end up sending their stuff to the old stdio fd (which might be invalid because the LabVIEW process was started up without console).

 

And here you basically run very likely into the problem that it simply can't be done outside of the actual DLL that wants to do redirection. As soon as you write a second DLL to do all this stuff it will link with a particular C runtime library (either dynamically or statically if you setup the project to include the C runtime in the DLL) and if your DLL was created with a different Visual C version than the DLL you want the redirection to work in they will link to different C runtime libraries that know nothing about the stdio redirection in the other one if both DLLs are set to link dynamically to the C runtime. If one of them is set to link to the static C runtime version they will use their own separate view of the stdio fds and then it fails anyhow.

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

I thought "A DLL doesn't have a stdin/stdout/stderr in itself. it inherits the stdin/stdout/stderr of whatever process the DLL is called from. ".

 

So shouldn't Console.Write in LV output to the same StdOut as the DLL running in LV?

 

Maybe the redirect needs to happen before the DLL is loaded?

0 Kudos
Message 36 of 47
(1,714 Views)
0 Kudos
Message 37 of 47
(1,711 Views)

Again, very good information.  Thank you rolfk. 

 

So it sounds like maybe I will need to build the dll with the redirect code built in using a wrapper maybe.

0 Kudos
Message 38 of 47
(1,698 Views)

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?

0 Kudos
Message 39 of 47
(1,694 Views)

wiebe@CARYA wrote:

I thought "A DLL doesn't have a stdin/stdout/stderr in itself. it inherits the stdin/stdout/stderr of whatever process the DLL is called from. ".

 

So shouldn't Console.Write in LV output to the same StdOut as the DLL running in LV?

 

Maybe the redirect needs to happen before the DLL is loaded?


Well it doesn't have it's own console since a process only can have zero or one console at any time. But the Standard C library uses internally file descriptors everywhere, which is basically an integer enumerating all the opened streams in the C runtime library. When a DLL is started up it also internally calls numerous routines that initialize the C runtime library and one of them associates the stdio fd's with the actual console stdio handles (and if they are invalid it maps them to an fd that is analogous to the famous /dev/nul device).

 

So it doesn't have its own stdio but it does require a separate mapping of stdio fd's to the actual console stdio handles, which are normal Windows stream handles.

 

 

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