Redirecting Stdout in imported DLL

Sep 24, 2010 at 5:32 PM

This isn't really a question about the DLR, but about how the DLR interfaces with imported DLL's from a DLR langauge.

Currently, I have an IronPython program that is embedded in a GUI. When I clr.AddReference and import the DLL, things work great. However, one of the DLL's I am bringing in has some output to stdout, and that goes to the terminal. I think I have the stdout of the DLR language engine set to redirect to my GUI.

The question: should the output of the included DLL be going to the redirected location? Or do I need to do something to set it? If so, is there any method of automatic initialization without writing my own import hooks?

-Doug

Coordinator
Sep 24, 2010 at 5:39 PM

There’s a tension here between the DLR being multi-instanced and supporting re-directing of std out vs. the CLR’s own set of standard I/O which is single instanced via static variables on the Console class. Anything which does it’s standard I/O via the DLR will correctly redirect to where you’ve configured it. But programs are still capable of going to Console which won’t automatically be redirected. So in addition to redirecting things at the DLR level you can call Console.SetOut / Console.SetError to make sure you capture “everything”. Of course something could still go to the Win32 APIs I guess but hopefully you don’t need to redirect that too J

From: dsblank [mailto:notifications@codeplex.com]
Sent: Friday, September 24, 2010 10:33 AM
To: Dino Viehland
Subject: Redirecting Stdout in imported DLL [dlr:228497]

From: dsblank

This isn't really a question about the DLR, but about how the DLR interfaces with imported DLL's from a DLR langauge.

Currently, I have an IronPython program that is embedded in a GUI. When I clr.AddReference and import the DLL, things work great. However, one of the DLL's I am bringing in has some output to stdout, and that goes to the terminal. I think I have the stdout of the DLR language engine set to redirect to my GUI.

The question: should the output of the included DLL be going to the redirected location? Or do I need to do something to set it? If so, is there any method of automatic initialization without writing my own import hooks?

-Doug

Read the full discussion online.

To add a post to this discussion, reply to this email (dlr@discussions.codeplex.com)

To start a new discussion for this project, email dlr@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Sep 24, 2010 at 6:14 PM

Thanks for the pointers on Console.SetOut. I'm wondering if there is any automatically run code that runs when a DLL in general is loaded where I could set such items? Something like Dllmain?

Or, alternatively should I write some kind of Initialization function that I would call whenever I add a reference to the DLL from the DLR infrastructure? I want the stdout to be redirected for all DLLs for all of my DLR languages. If my DLR system were in IronPython, something like:

for dll_file in dlls:
    clr.AddReference(dll_file)
    __import__(dll_file) # or maybe run directly from clr.Reference[] without import?
    exec("%s.Initialize(%s)" % (dll_file, sys.stdout))

Thanks for any helpful suggestions working around this,

-Doug

 

Coordinator
Sep 24, 2010 at 6:20 PM

You can just do this at any point when you startup your process – std out is global so you can do it once and all DLLs will see the new value. I’d suggest doing it when you’re creating the ScriptRuntime and redirecting I/O there.

From: dsblank [mailto:notifications@codeplex.com]
Sent: Friday, September 24, 2010 11:15 AM
To: Dino Viehland
Subject: Re: Redirecting Stdout in imported DLL [dlr:228497]

From: dsblank

Thanks for the pointers on Console.SetOut. I'm wondering if there is any automatically run code that runs when a DLL in general is loaded where I could set such items? Something like Dllmain?

Or, alternatively should I write some kind of Initialization function that I would call whenever I add a reference to the DLL from the DLR infrastructure? I want the stdout to be redirected for all DLLs for all of my DLR languages. If my DLR system were in IronPython, something like:

for dll_file in dlls:
clr.AddReference(dll_file)
__import__(dll_file) # or maybe run directly from clr.Reference[] without import?
exec("%s.Initialize(%s)" % (dll_file, sys.stdout))

Thanks for any helpful suggestions working around this,

-Doug

Read the full discussion online.

To add a post to this discussion, reply to this email (dlr@discussions.codeplex.com)

To start a new discussion for this project, email dlr@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Sep 24, 2010 at 6:31 PM

You mean like:

engine.Runtime.IO.SetOutput(stdout, System.Text.Encoding.UTF8)

If so, that doesn't seem to work (ie, imported DLLs do not have their output redirected). But if it should, then perhaps I am doing something wrong. If this isn't want you mean, can you hum a few more bars?

Thanks!

-Doug

Coordinator
Sep 24, 2010 at 6:37 PM

I mean like:

engine.Runtime.IO.SetOutput(stdout, System.Text.Encoding.UTF8)

Console.SetOut(engine.Runtime.IO.OutputWriter);

This is more complicated if the ScriptRuntime is in a remote app domain. Then you’ll need to call into the domain and do this. I think something like:

[Serializable]

class Callback {

private readonly TextWriter _writer;

public Callback(TextWriter writer) {

_writer = writer;

}

public void SetOut() {

Console.SetOut(_writer);

}

}

AppDomain.CurrentDomain.DoCallBack(new Callback(engine.Runtime.IO.OutputWriter).SetOut);

Should work.

From: dsblank [mailto:notifications@codeplex.com]
Sent: Friday, September 24, 2010 11:32 AM
To: Dino Viehland
Subject: Re: Redirecting Stdout in imported DLL [dlr:228497]

From: dsblank

You mean like:

engine.Runtime.IO.SetOutput(stdout, System.Text.Encoding.UTF8)

If so, that doesn't seem to work (ie, imported DLLs do not have their output redirected). But if it should, then perhaps I am doing something wrong. If this isn't want you mean, can you hum a few more bars?

Thanks!

-Doug

Read the full discussion online.

To add a post to this discussion, reply to this email (dlr@discussions.codeplex.com)

To start a new discussion for this project, email dlr@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Sep 25, 2010 at 12:55 AM

>>> Console.SetOut(engine.Runtime.IO.OutputWriter)

Of course! Working with the DLR and .NET is mind altering. Yes, I forgot that we're all in the same space, so a call to System.Console is the same at the IronPython level as it is in the DLL. 

Thanks! Is now working.

-Doug